web-dev-qa-db-ja.com

AngularJSのngIncludeディレクティブにモデルを指定する方法は?

同じHTMLテンプレートを3つの場所で、毎回異なるモデルで使用したいと思います。テンプレートから変数にアクセスできることは知っていますが、名前は異なります。

モデルをngIncludeに渡す方法はありますか?

これは私が達成したいことです。もちろん、属性add-variableは今は機能しません。次に、含まれているテンプレートで、detailsObjectとそのプロパティにアクセスします。

<pane title="{{projectSummary.ProjectResults.DisplayName}}">
    <h2>{{projectSummary.ProjectResults.DisplayName}}</h2>
    <ng-include src="'Partials/SummaryDetails.html'" init-variable="{'detailsObject': projectSummary.ProjectResults}"></ng-include>
</pane>

<pane  title="Documents" header="true"></pane>

<pane ng-repeat="document in projectSummary.DocumentResults" title="{{document.DisplayName}}">
    <h2>{{document.DisplayName}}</h2>
    <ng-include src="'Partials/SummaryDetails.html'" add-variable="{'detailsObject': document}"></ng-include>
</pane>

<pane ng-repeat="header in [1]" title="Languages" header="true"></pane>

<pane ng-repeat="language in projectSummary.ResultsByLanguagePairs" title="{{language.DisplayName}}">
    <h2>{{document.DisplayName}}</h2>
    <ng-include src="'Partials/SummaryDetails.html'" add-variable="{'detailsObject': language}"></ng-include>
</pane>

Ng-includeを使用して悪いアプローチをとった場合、他に試してみるべきことがありますか?

44
Tomas Grosup

注:これは私の元の答えではありませんが、これはangularを少し使用した後にこれを行う方法です。

this fiddle に見られるように、動的データをディレクティブに渡すマークアップとしてhtmlテンプレートを使用してディレクティブを作成します。

この例の手順/注意:

  1. templateUrlにマークアップを使用してディレクティブを定義し、ディレクティブにデータを渡すために使用される属性(この例ではtypeという名前)を定義します。
  2. テンプレートのディレクティブデータ(この例ではtypeという名前)を使用します。
  3. マークアップでディレクティブを使用する場合は、コントローラースコープからディレクティブにデータを渡すようにしてください(<address-form type="billing"></address-form>(請求書がコントローラースコープのオブジェクトにアクセスしている場合)。
  4. ディレクティブを定義する場合、名前はキャメルケースになりますが、マークアップで使用する場合は、ダッシュで区切られた小文字です(つまり、jsではaddressFormという名前ですが、address-formのhtml)。これに関する詳細は、angular docs here にあります。

これがjsです:

var myApp = angular.module('myApp',[]);

angular.module('myApp').directive('addressForm', function() {
    return {
        restrict: 'E',
        templateUrl: 'partials/addressform.html', // markup for template
        scope: {
            type: '=' // allows data to be passed into directive from controller scope
        }
    };
});

angular.module('myApp').controller('MyCtrl', function($scope) {
    // sample objects in the controller scope that gets passed to the directive
    $scope.billing = { type: 'billing type', value: 'abc' };
    $scope.delivery = { type: 'delivery type', value: 'def' };
});

マークアップあり:

<div ng-controller="MyCtrl">
    <address-form type="billing"></address-form>
    <address-form type="delivery"></address-form>
</div>

オリジナルの回答(ディレクティブBTWを使用した場合とはまったく異なります)。

注:以下の元の回答のフィドルは、エラーが原因で機能しなくなったようです(ただし、まだ有用な場合に備えて、ここに保管してください)

これについては、できる限りGoogleグループで議論しました こちらをご覧ください

この機能は初期状態ではサポートされていないようですが、 この投稿 で説明されているように、Briceのパッチを使用できます。

彼の jsfiddle のサンプルコードを次に示します。

<script id="partials/addressform.html" type="text/ng-template">
    partial of type {{type}}<br>
</script>

<div ng-controller="MyCtrl">
  <ng-include src="'partials/addressform.html'" onInclude="type='billing'"></ng-include>
  <ng-include src="'partials/addressform.html'" onLoad="type='delivery'"></ng-include>
</div>
20
Gloopy

かなり簡単な解決策がありますが、私は認めなければなりませんが、それはMiskoが推奨するものではありません。しかし、ディレクティブの作成があなたにとってやり過ぎであり、Briceのパッチを入手することが現実的でない場合は、以下が役立ちます。

<div ng-repeat="name in ['A']" ng-include="'partial.html'"></div>
<div ng-repeat="name in ['B']" ng-include="'partial.html'"></div>

<script type="text/ng-template" id="partial.html">
   <div>{{ name }}</div>
</script>

なぜ機能するのかは明らかです。こちらの例をご覧ください: http://jsfiddle.net/Cndc6/4/

61
Denis Pshenov

これを修正するプルがありますが、死んでいるようです: https://github.com/angular/angular.js/pull/1227

Angularソースコードを修正せずに、これは再利用可能なあまりハック感のない方法で問題を解決します:

directive('newScope', function() {
    return {
        scope: true,
        priority: 450,
    };
});

そして例:

<div new-scope ng-init="myVar = 'one instance'" ng-include="'template.html'"></div>
<div new-scope ng-init="myVar = 'another instance'" ng-include="'template.html'"></div>

動作中のプランカーは次のとおりです。 http://plnkr.co/edit/El8bIm8ta97MNRglfl3n

14
John Culviner
<div new-scope="myVar = 'one instance'" ng-include="'template.html'"></div>

directive('newScope', function () {
    return {
        scope: true,
        priority: 450,
        compile: function () {
            return {
                pre: function (scope, element, attrs) {
                    scope.$eval(attrs.newScope);
                }
            };
        }
    };
});

これは、 John Culviner's answernew-scopeを、Angularのng-initのコードと組み合わせたディレクティブです。

完全を期すために、これは Angular 1.2 26 ng-init source です。new-scopeディレクティブの唯一の変更は、scope: trueの追加です。

{
  priority: 450,
  compile: function() {
    return {
      pre: function(scope, element, attrs) {
        scope.$eval(attrs.ngInit);
      }
    };
  }
}
6
Ande

Quick'n'dirtyソリューション:

<div ng-init="details=document||language||projectSummary.ProjectResults">
5
Tomas Grosup

私はあなたを聞く! ng-includeはグローバルスコープにアクセスできるため、それほど再利用できません。ちょっと変です。

ローカル変数を設定する方法が必要です。 ng-includeの代わりに新しいディレクティブを使用する は、よりクリーンなソリューションです。

理想的な使用法は次のとおりです。

<div ng-include-template="'Partials/SummaryDetails.html'" ng-include-variables="{ 'detailsObject': language }"></div>

ディレクティブは次のとおりです。

.directive(
  'ngIncludeTemplate'
  () ->
    {
      templateUrl: (elem, attrs) -> attrs.ngIncludeTemplate
      restrict: 'A'
      scope: {
        'ngIncludeVariables': '&'
      }
      link: (scope, elem, attrs) ->
        vars = scope.ngIncludeVariables()
        for key, value of vars
          scope[key] = value
    }
)

ディレクティブがグローバルスコープを使用していないことがわかります。代わりに、ng-include-variablesからオブジェクトを読み取り、それらのメンバーを独自のローカルスコープに追加します。

クリーンで汎用的です。

1
Tanin