微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

混淆关于Angularjs transcluded和隔离范围和绑定

我很难理解范围有限的指令的范围和它们的绑定。

我认为限制指令的范围意味着controller。scope和directive.scope不再是同一个东西。然而,我困惑的是如何将模型放置在指令模板内或在html中影响数据绑定。我觉得我错过了一些非常根本的东西,继续前进,我需要理解这一点。

拿下面的代码(这里调用http://jsfiddle.net/2ams6/)

JavaScript

var app = angular.module('app',[]);
app.controller('Ctrl',function($scope){
});
app.directive('testel',function(){
    return {
        restrict: 'E',scope: {
            title: '@'
        },transclude: true,template:   '<div ng-transclude>'+
                    '<h3>Template title: {{title}}</h3>' +
                    '<h3>Template data.title:{{data.title}}</h3>' +
                    '</div>'
    }    
});

HTML

<div ng-app='app'>
    <div ng-controller="Ctrl">
        <input ng-model="data.title">
        <testel title="{{data.title}}">
            <h3>Transclude title:{{title}}</span></h3>
            <h3>Transclude data.title:{{data.title}}</h3>
        </testel>
    </div>
</div>

模型仅更新模板中的{{title}},并更新互换中的{{data.title}}。为什么模板中的{{title}}不是{{data.title}}?

将输入移动到这样的转换中(这里:http://jsfiddle.net/eV8q8/1/):

<div ng-controller="Ctrl">
    <testel title="{{data.title}}">
        <input ng-model="data.title">
         <h3>Transclude title: <span style="color:red">{{title}}</span></h3>

         <h3>Transclude data.title: <span style="color:red">{{data.title}}</span></h3>

    </testel>
</div>

现在意味着只有transclude {{data:title}}得到更新。为什么不使用模板{{title}}或{{data.title}},也不转换{{title}}?

最后,将输入移动到模板中,如下所示(fiddle here:http://jsfiddle.net/4ngmf/2/):

template: '<div ng-transclude>' +
            '<input ng-model="data.title" />' +
            '<h3>Template title: {{title}}</h3>' +
            '<h3>Template data.title: {{data.title}}</h3>' +
            '</div>'

现在意味着只有模板{{data.title}}得到更新。再次,为什么不是其他3绑定?

我希望有一些明显的盯着我在脸上,我错过了。如果你让我得到这个,我会给你买啤酒,或给你一些点,或一些其他这样的事情。非常感谢。

你的fiddles创建三个范围:

>与控制器Ctrl相关联的范围,因为ng-controller
>一个指令的transcluded作用域,因为transclude:true
> a指令隔离范围,因为范围:{…}

fiddle1中,在我们在文本框中输入任何内容之前,我们有以下:

范围003是与控制器关联的范围。因为我们没有键入到文本框中,所以没有数据属性。在隔离范围004中,我们看到创建了一个title属性,但它是空的。它为空,因为父作用域还没有data.title属性

在文本框中输入我的标题后,我们现在有:

控制器范围003现在有一个新的数据对象属性(这是为什么它是黄色的),它有一个title属性现在设置为我的标题。因为隔离范围属性标题是单向数据绑定到data.title的内插值,它也获得值my标题(该值是黄色,因为它改变)。

被转换的范围原型上继承于控制器范围,因此在转换的HTML中,angular可以遵循原型链,并在父范围中找到$ scope.data.title(但$ scope.title不存在)。

隔离范围只能访问其自己的属性,因此只有属性标题

fiddle2中,在输入之前我们有和fiddle1一样的图片

输入我的标题后:

注意新的data.title属性显示在转录作用域上的位置。隔离范围仍然在控制器范围上寻找data.title,但是它在这里没有,所以它的title属性值保持为空。

fiddle3中,在打字之前我们有和fiddle1一样的图片

输入我的标题后:

注意新的data.title属性显示在隔离范围上的位置。其他任何作用域都无法访问隔离作用域,因此字符串my title不会出现在其他位置。

更新Angular v1.2:

With change eed299a Angular现在在转义之前清除了转义点,因此Template title:…和Template data.title:…部分不会显示,除非您修改模板,以使ng-transclude本身,例如如:

'<h3>Template title: <span style="color:red">{{title}}</span></h3>' +
'<h3>Template data.title: <span style="color:red">{{data.title}}</span></h3>' +
'<div ng-transclude></div>'

在下面的更新Angular v1.3,这个模板更改。

Angular v1.3的更新:

从Angular v1.3开始,被转换的作用域现在是指令的孤立作用域的子元素,而不是控制器作用域的子元素。所以在fiddle1,在我们输入任何东西之前:

本更新中的图片是用Peri$scope工具绘制的,因此图片有点不同。 @表示我们有一个使用@语法的隔离范围属性,粉红色的背景意味着该工具无法为映射找到一个祖先引用(这是真的,因为我们没有在文本框中输入任何内容)。

在文本框中输入我的标题后,我们现在有:

使用@ binding的隔离属性将始终在@符号后的隔离范围中显示插值字符串结果。 Peri $ scope也能够在祖先范围中找到此精确的字符串值,因此它也显示对该属性的引用。

在小提琴2,在打字之前我们有和fiddle1一样的图片

输入我的标题后:

注意新的data.title属性显示在转录作用域上的位置。隔离范围仍然在控制器范围上寻找data.title,但是它在这里没有,所以它的title属性值保持为空。

fiddle3中,在打字之前我们有和fiddle1一样的图片

输入我的标题后:

注意新的data.title属性显示在隔离范围上的位置。即使转录作用域通过$ parent关系访问了孤立作用域,它也不会查找title或data.title – 它只会查找控制器作用域(即它将遵循原型继承)并且控制器作用域没有定义这些属性

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐