不应该有AngularJS ngWith指令吗?

前端之家收集整理的这篇文章主要介绍了不应该有AngularJS ngWith指令吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
也许我很疯狂,或者也习惯了 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>

但是在这两种情况下,我想象我的范围是从我的模型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>

这似乎对我来说无限有用。

我在这里遗漏了什么吗?只是让自己的麻烦让人不知所措吗?

这是一个很好的问题。我可以看到这可能会来自另一个前端框架,但是在Angular中,范围引用了模型,并且您描述的语法是正常的。我个人喜欢将范围描述为更像 a view model

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

猜你在找的Angularjs相关文章