Возможно, я сумасшедший или слишком привык к KnockoutJS, но я продолжаю искать директиву ngWith в документах для определения области действия элемента, в контроллере или для частичного включения (ngInclude).
Например:
Я бы хотел написать контроллер, который добавляет MyItem:
MyModule.controller('MyItemCtrl', function($scope) {
$scope.doSomethingToItem = function() {
$scope.name = "bar";
};
});
Или представление/шаблон для MyItem like:
<div ng-controller="MyItemCtrl">
{{name}}
<button ng-click="doSomethingWithItem()">Do Something</button>
</div>
Но в обоих случаях я предполагаю, что моя $scope будет прототипически унаследована от моей модели MyItem
.
Но область не наследуется от модели!!
Что меня озадачивает.
Вместо этого моя модель является свойством в области.
В случае ретранслятора:
<div ng-repeat="item in list">
<div ng-controller="MyItemCtrl">
{{item.name}}
<button ng-click="doSomethingWithItem()">Do Something</button>
</div>
</div>
что означает, что везде я должен использовать item.this
или item.that
вместо this
и that
. Я должен помнить, какие функции являются родными для модели и которые были применены непосредственно к сфере действия контроллером.
Если я хочу иметь частичное отображение имен (тупой пример, я знаю, но вы понимаете):
<h3>{{name}}</h3>
Мне нужно написать его
<h3>{{item.name}}</h3>
а затем убедитесь, что модель всегда является элементом. Обычно, обертывая его в директиве, просто определяет область действия с свойством item
.
То, что я часто чувствую, что хочу сделать, просто:
<div ng-include="'my/partial.html'" ng-with="item"></div>
или
<div ng-repeat="list" ng-controller="MyItemCtrl">
{{name}}
<button ng-click="doSomethingWithItem()">Do Something</button>
</div>
Есть ли какая-то магическая директива, которую я не нашел? Или я совершенно неправ и просто ищу проблемы?
Спасибо.
EDIT:
Большое спасибо Брэндону Тилли за объяснение опасности использования областей в качестве моделей. Но я все еще часто нахожу необходимость в некоторой быстрой декларативной манипуляции с областью и желаю директивы ng-with.
Возьмем, например, список элементов, которые при щелчке показывают расширенный вид выбранного элемента. Вы можете написать что-то вроде:
<ul>
<li ng-repeat="item in items" ng-click="selection = item">{{item.minView}}</li>
</ul>
<div ng-controller="ItemController">
{{selection.maxView}}
</div>
теперь вам нужно получить свойства выбранного элемента, используя selection.property
, а не то, что я хочу: item.property
. Мне также пришлось бы использовать selection
в ItemController
! Составляя это полностью вместе с этим представлением.
Я знаю, в этом простом примере я мог бы иметь контроллер упаковки, чтобы он работал, но это иллюстрирует эту точку.
Я написал очень базовую директиву with
:
myApp.directive('with', ['$parse', '$log', function(parse, log) {
return {
scope: true,
link: function(scope, el, attr) {
var expression = attr.with;
var parts = expression.split(' as ');
if(parts.length != 2) {
log.error("`with` directive expects expression in the form `String as String`");
return;
}
scope.$watch(parts[0], function(value) {
scope[parts[1]] = value;
}, true);
}
}
}]);
который просто создает новую область, анализируя одно выражение на другое значение, позволяя:
<ul>
<li ng-repeat="item in items" ng-click="selection = item">{{item.minView}}</li>
</ul>
<div with="selection as item" ng-controller="ItemController">
{{item.maxView}}
</div>
Это кажется мне бесконечно полезным.
Я что-то упустил? Просто как-то беспокоиться о себе?