也许我疯了,或者太习惯于KnockoutJS,但我一直在文档中寻找 ngWith 指令来定义元素、控制器或包含的 (ngInclude) 部分的范围。
例如:
我想编写一个增强 MyItem 的控制器,例如:
MyModule.controller('MyItemCtrl', function($scope) {
$scope.doSomethingToItem = function() {
$scope.name = "bar";
};
});
或 MyItem 的视图/模板,例如:
<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
oritem.that
而不是this
and 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>
是否有一些我没有找到的神奇指令?还是我完全错了,只是在找麻烦?
谢谢。
编辑:
非常感谢 Brandon Tilley 解释了使用示波器作为模型的危险。但我仍然经常发现需要一些快速的声明性范围操作,并希望使用 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
in 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>
这对我来说似乎无限有用。
我在这里错过了什么吗?只是以某种方式为自己制造麻烦?