例如:
我想编写一个增加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>
但是在这两种情况下,我想象我的范围是从我的模型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而不是这个和那个。我必须记住哪些函数是模型的本机,哪些函数由控制器直接应用于范围。
如果我想要部分显示名称(愚蠢的例子,我知道,但你得到的想法):
<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。我也必须在ItemController中使用选择!使其完全结合这一观点。
我知道,在这个简单的例子中,我可以有一个包装控制器来使其工作,但它说明了一点。
我写了一个非常基本的指令:
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>
这似乎对我来说无限有用。
我在这里遗漏了什么吗?只是让自己的麻烦让人不知所措吗?
AngularJS的作者MiškoHevery在this video,starting at about the 30 minute mark and lasting about 3 minutes年做了很好的解释:
People oftentimes think that the scope is the model,and that’s not the case. Scope has references to the model. […] So in the view,you say
model dot
whatever property you want to access.
虽然可能会编写一个ngWith指令,这样你可以找到所需要的内容,但由于Angular使用了原型继承的范围,所以您可能会遇到Miško在上述视频at 31:10中所描述的相同问题您正在更新父范围上的值,但实际上不是)。有关AngularJS中原型继承的更多细节,请查看AngularJS wiki上的优秀文章The Nuances of Scope Prototypal Inheritance。