AngularJS:包含和范围继承=损坏的绑定?

Posted

技术标签:

【中文标题】AngularJS:包含和范围继承=损坏的绑定?【英文标题】:AngularJS: Include and scope inheritance = broken bindings? 【发布时间】:2013-03-20 06:57:01 【问题描述】:

为了清理我的局部菜单,我最近将一些全局菜单移到了单独的模板中,现在我将这些模板包含在需要它们的视图中。由于菜单(包括搜索栏)是全局的,我创建了一个服务来跟踪菜单的状态等等。

问题是在我开始包含之后发生了一些有趣的事情。

视图的 HTML (Jade)

div(ng-controller='HeroUnitCtrl', ng-include src='heroTemplate')
div(ng-controller='MainSearchBarCtrl', ng-include src='searchBarTemplate')

div.row-fluid
    div.span12
        table.table.table-striped.table-bordered
            tr
                th
                    a(ng-click='setOrder("id")') ID#
                th
                    a(ng-click='setOrder("client.name")') Kunde
                th
                    a(ng-click='setOrder("technician.name")') Tekniker
                th
                    a(ng-click='setOrder("createdAt")') Opprettet
                th
                    a(ng-click='setOrder("statusString")') Status

            tr(ng-repeat='record in records | orderBy:orderProp | filter:searchBar')
                td
                    a(ng-href='#/records/show/record.id') record.id
                td record.client.name
                td record.technician.name
                td record.createdAt
                td record.statusString

HTML (Jade) 搜索栏模板

input#searchField.input-xxlarge(type='text', placeholder='placeholder', ng-change='searchBarUpdated()', ng-model='searchBar')

现在我真的不明白,

MainSearchBarCtrl

function MainSearchBarCtrl(MainSearchBarService, $scope, $location) 
    $scope.searchBarTemplate = 'partials/main-searchbar';
    $scope.searchBar = 'Hello World!';

    $scope.searchBarUpdated = function() 
        console.log('Search bar update: ' + $scope.searchBar);
        MainSearchBarService.searchBarUpdated($scope.searchBar);
       

searchBar 的值最初是预期的“Hello World”。但是,如果我附加任何文本,它仍然只打印“Hello World”。或者,如果我替换它打印未定义的文本。所以看起来绑定被打破了,但我真的不明白为什么会这样。值得一提的是,在我将搜索栏移到单独的模板中之前,情况并非如此。

非常感谢任何帮助。

【问题讨论】:

创建一个复制问题的演示 好的,我会搞定的。如果您查看视图的顶部,它包括 searchBarTemplate。 我修改了关于范围的评论......但如果没有看到实时版本就很难提供帮助 ng-include 创建一个新的子范围。因此,在您的 searchBarTemplate 中,使用 ng-model="searchBar" 会在子范围内创建一个新的 searchBar 属性,该属性会隐藏/隐藏同名的父 searchBar 属性。尝试在控制器中使用$scope.obj = searchBar: 'Hello World!,在模板中使用ng-model="obj.searchBar" @MarkRajcok 解决了问题,将来更容易将演示放在 Plunker 中,这样它们就可以被编辑并且更容易审查代码。允许为部分和不同的 js 文件等非常简单地创建外部文件 【参考方案1】:

正如上面 cmets 中所讨论的,ng-include 创建了一个新的子作用域。因此,在您的 searchBarTemplate 中,使用 ng-model="searchBar" 会在子范围内创建一个新的 searchBar 属性,该属性会隐藏/隐藏同名的父 searchBar 属性。

在控制器中,定义一个对象:

$scope.obj = searchBar: 'Hello World!;

然后使用

ng-model="obj.searchBar" 

在您的模板中。当使用对象(而不是原语)时,子作用域不会创建新属性。而是由于javascript prototypal inheritance works的方式,子作用域会在父作用域上找到属性。

另请参阅https://***.com/a/14146317/215945,其中有一张图片显示了子范围和父范围,以及在使用原语时子属性如何隐藏/隐藏父属性。

请注意,使用$parent 是另一种选择,但这不是“最佳实践”。

【讨论】:

优秀。谢谢你的详细回答。 只是快速跟进。是否可以从父范围访问子范围?我猜不是因为继承,而是。 不...是的,但是您必须使用 Angular 私有 $$ 变量,例如 $$childHead 等。我不建议这样做(永远)。 这个和controllerAs语法看起来一样吗?【参考方案2】:

尝试在包含的模板中使用 $parent 而不是 $scope

【讨论】:

我认为这是个坏主意。将您的代码移动到局部视图或指令内,或两者兼而有之,您的代码不再工作。为了让它工作,你必须使用 $parent.$parent.... github.com/angular/angular.js/wiki/…

以上是关于AngularJS:包含和范围继承=损坏的绑定?的主要内容,如果未能解决你的问题,请参考以下文章

很easy的js双向绑定框架:控制器继承

在自定义指令的范围绑定中使用符号“@”、“&”、“=”和“>”:AngularJS

AngularJS - ng-include ng-controller 和范围不绑定

AngularJS之基础-4 DI(控制器参数监听)指令(模板包含节点控制)事件绑定

AngularJS 中范围原型/原型继承的细微差别是啥?

复选框未绑定到angularjs中的范围