Подтвердить что ты не робот

Как указать модель в директиву ngInclude в AngularJS?

Я хотел бы использовать один и тот же шаблон HTML в трех местах, каждый раз с другой моделью. Я знаю, что могу получить доступ к переменным из шаблона, но имена будут разными.

Есть ли способ передать модель в 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, есть ли что-то еще, что я должен попробовать?

4b9b3361

Ответ 1

ПРИМЕЧАНИЕ. Это не мой первоначальный ответ, но так я сделал бы это после использования angular для бит.

Я бы создал директиву с шаблоном html как разметку, передаваемую динамическими данными в директиву, как показано в этой скрипке.

Шаги/примечания для этого примера:

  • Определите директиву с разметкой в ​​ templateUrl и атрибутах (ах), используемых для передачи данных в директиву (с именем type в этом примере).
  • Используйте данные директивы в шаблоне (с именем type в этом примере).
  • При использовании директивы в разметке убедитесь, что вы передали данные из области контроллера в директиву (<address-form type="billing"></address-form> (где биллинг обращается к объекту в области контроллера).
  • Обратите внимание, что при определении директивы имя является верблюжьим, но при использовании в разметке оно ограничено нижним регистром (т.е. оно называется addressForm в js, но address-form в html). Подробнее об этом можно узнать в angular docs здесь.

Вот 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>

Ответ 2

Существует довольно простое решение, хотя я должен признать, что это не то, что Мишко рекомендовал бы. Но если создание директивы является излишним для вас и получение патча 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/

Ответ 3

Есть повод, чтобы исправить это, но похоже, что он мертв: 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

Ответ 4

Решение Quick'n'dirty:

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

Ответ 5

<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);
                }
            };
        }
    };
});

Это директива, объединяющая new-scope from ответ Джона Кулвинера с кодом от Angular ng-init.

Для полноты, это Angular 1.2 26 ng-init source, вы можете увидеть единственное изменение в новой области директива - это добавление scope: true

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

Ответ 6

Я тебя слышу! 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 и добавляет эти члены в свою собственную локальную область.

Он чистый и общий.