nic*_*las 21 angularjs angularjs-scope
也许我疯了,或者习惯于KnockoutJS,但我一直在文档中寻找一个ngWith指令来定义元素,控制器或包含(ngInclude)部分的范围.
例如:
我想编写一个增强MyItem的控制器,如:
MyModule.controller('MyItemCtrl', function($scope) {
$scope.doSomethingToItem = function() {
$scope.name = "bar";
};
});
Run Code Online (Sandbox Code Playgroud)
或MyItem的视图/模板,如:
<div ng-controller="MyItemCtrl">
{{name}}
<button ng-click="doSomethingWithItem()">Do Something</button>
</div>
Run Code Online (Sandbox Code Playgroud)
但在这两种情况下,我都在想象我的范围是从我的模型继承原型,MyItem.
但范围不继承模型!!
哪个让我感到困惑.
相反,我的模型是范围上的属性.
在转发器的情况下:
<div ng-repeat="item in list">
<div ng-controller="MyItemCtrl">
{{item.name}}
<button ng-click="doSomethingWithItem()">Do Something</button>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
这意味着我必须使用item.this或item.that代替只是this和that.我必须记住哪些函数是模型的原生函数,哪些函数由控制器直接应用于作用域.
如果我想部分显示名称(愚蠢的例子,我知道,但你明白了):
<h3>{{name}}</h3>
Run Code Online (Sandbox Code Playgroud)
我必须写它
<h3>{{item.name}}</h3>
Run Code Online (Sandbox Code Playgroud)
然后确保模型始终是项目.通常通过将其包装在指令中来简单地定义具有item属性的范围.
我经常想要做的事情就是:
<div ng-include="'my/partial.html'" ng-with="item"></div>
Run Code Online (Sandbox Code Playgroud)
要么
<div ng-repeat="list" ng-controller="MyItemCtrl">
{{name}}
<button ng-click="doSomethingWithItem()">Do Something</button>
</div>
Run Code Online (Sandbox Code Playgroud)
那里有一些我没有找到的神奇指令吗?或者我完全错了,只是找麻烦?
谢谢.
编辑:
非常感谢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>
Run Code Online (Sandbox Code Playgroud)
现在你必须使用所选项目的属性,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);
}
}
}]);
Run Code Online (Sandbox Code Playgroud)
只是创建一个新的范围,将一个表达式解析为另一个值,允许:
<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>
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎无限有用.
我在这里错过了什么吗?不管怎么说,只为自己制造麻烦?
Har*_*rry 21
我发现我可以在ng-repeat的源头周围放一个数组,它在功能上变成了ng-with.:)
<div ng-repeat="name in [vm.dto.Person.Name]" >
<input type="text" ng-model="name.First" />
<input type="text" ng-model="name.Last" />
</div>
Run Code Online (Sandbox Code Playgroud)
似乎有些纯净可能不喜欢这样......也似乎没有一个好的选择.
Mic*_*ley 10
这是一个很好的问题.我可以看到这可能会让来自另一个前端框架的混淆,但是在Angular中,范围有对模型的引用,并且您描述的语法是正常的.我个人喜欢将范围描述为更像视图模型.
AngularJS的作者MiškoHevery在这段视频中做了很好的解释,从约30分钟开始,持续约3分钟:
人们经常认为范围是模型,而事实并非如此.范围引用了该模型.[...]因此,在视图中,您说出
model dot您想要访问的任何属性.
虽然有可能编写一个ngWith指令来实现您正在寻找的类型,但由于Angular使用原型继承作为范围,您可能会遇到Miško在上述视频中描述的相同问题(31:10)你认为你正在更新父范围的值,但实际上你没有).有关AngularJS中原型继承的更多详细信息,请参阅AngularJS wiki上的优秀文章范围原型继承的Nuances.
另一种方法是通过以下方式设置新变量ng-init:
<div ng-init="name = vm.dto.Person.Name" >
<input type="text" ng-model="name.First" />
<input type="text" ng-model="name.Last" />
</div>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4293 次 |
| 最近记录: |