Angular - 改变范围没有得到反映 [英] Angular - Changing scope is not getting reflected

查看:23
本文介绍了Angular - 改变范围没有得到反映的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这很奇怪,因为它应该非常简单.我会先贴出我的代码,然后再提问:

html -

<div>{{addCustom}}//不会改变<div ng-if="addCustom === false">{{addCustom}}//确实发生了变化<button type="button" class="btn btn-primary btn-icon-text" ng-click="addCustom = true"><span class="icon icon-plus"></span>点击这里

控制器 -

(function(){'使用严格';angular.module('myApp').controller('myController',['$scope',myController]);功能 myController($scope){$scope.addCustom = false;}})();

所以我只是在我的控制器中引入了一个范围变量 - addCustom - 并将其设置为 false 作为默认值.此变量控制是否显示 div.我还在 2 个不同位置的 html 上输出范围的值.请参阅上文.

但是当我在这个 div 中的 ng-click 中更改它的值时,它的值在第二个位置(div 内)发生变化,而不是第一个(div 外).因此,div 也不会改变状态.

我无法弄清楚这里可能有什么问题.有人可以帮忙吗?

解决方案

当你有 ng-repeatng-switchng 时,事情就发生了-if 指令,angular 会为这些元素的放置位置创建子作用域.那些新创建的范围通常是从父范围继承的.

对比 原型继承 是什么意思?

如果您有作用域层次结构,则 parent 作用域属性可在子作用域内访问,前提是这些属性是对象(最初引用的对象被传递给子作用域而不创建新的引用).但是原始数据类型在子范围内不可访问,如果您查看代码,addCustom 范围变量是原始数据类型.

<小时>

让我们讨论更多.

这里有 myController 控制器,它具有原始类型的 addCustom 范围变量 &正如我上面所说的 ng-switch &ng-if 指令被编译,它们会在该元素上创建新的子作用域.因此,在您当前的标记中,您在 ng-controller="myController" div 本身上有 ng-switch.对于内部 html,它创建了一个子作用域.如果您想访问 child(原始类型)内的父作用域,您可以在作用域变量名称之前使用 $parent 表示法.现在您可以通过 $parent.addCustom 访问 addCustom 值.当 angular 编译器来到 ng-if div 时,这里还没有结束,它会再次创建新的子作用域.现在 ng-if 的内部容器将再次具有子作用域,该子作用域原型继承自父级.不幸的是,在您的情况下,您有原始 dataType 变量,因此您需要再次使用 $parent 表示法.因此,在 ng-if div 中,您可以通过执行 $parent.$parent.addCustom 来访问 addCustom.这个 $parent 的东西会解决你的问题,但是把它放在 HTML 上会使它变得不可读并且与它的父作用域紧密耦合(假设在 UI 上你有 5 个子作用域,那么它看起来像 $parent.$parent.$parent.$parent).因此,您应该采用以下方法.

<小时>

在定义ng-model

时遵循Dot rule

所以我会说你需要创建一些像 $scope.model = {} 的对象,并向它添加 addCustom 属性.这样它将遵循原型继承原则,子作用域将使用由父级创建的相同对象.

angular.module('myApp').controller('myController',['$scope',myController]);功能 myController($scope){$scope.model = { addCustom : false };}

在 HTML 上,您将使用 model.addCustom 而不是 addCustom

标记

<div>{{model.addCustom}}//不会改变<div ng-if="model.addCustom === false">{{model.addCustom}}//确实发生了变化<button type="button" class="btn btn-primary btn-icon-text" ng-click="model.addCustom = true"><span class="icon icon-plus"></span>点击这里

处理此类问题的其他最佳方法是,在 HTML 上使用控制器时使用 controllerAs 模式.

标记

<div>{{myCtrl.addCustom}}//不会改变<div ng-if="myCtrl.addCustom === false">{{myCtrl.addCustom}}//确实发生了变化<button type="button" class="btn btn-primary btn-icon-text" ng-click="myCtrl.addCustom = true"><span class="icon icon-plus"></span>点击这里

This is weird as it should be pretty straightforward. I will post my code first and then ask the question:

html -

<div ng-controller="myController" ng-switch on="addressCards">

    <div>
        {{addCustom}} // does not get changed
        <div ng-if="addCustom === false">

            {{addCustom}} // does get changed
            <button type="button" class="btn btn-primary btn-icon-text" ng-click="addCustom = true">
                <span class="icon icon-plus"></span>
                click here
            </button>
        </div>
    </div>
</div>

controller -

(function(){
'use strict';

angular.module('myApp')
    .controller('myController',['$scope',myController]);


function myController($scope){ 

    $scope.addCustom = false;

}


})();

So I simply introduced a scope variable - addCustom - in my controller and set it to false as default. This variable controls if a div is shown or not. I am also outputting the value of the scope on the html at 2 different locations. Please see above.

But when I change its value in an ng-click within this divs, its value is changing at the second location(within the div) but not the first one(outside the div). Because of this the div does not change state as well.

I am not able to figure what might be possibly wrong here. Can someone please help?

解决方案

The thing happening is when you have ng-repeat,ng-switch and ng-if directive, angular creates child scope for those element wherever they are placed. Those newly created scope are prototypically inherited from there parent scope.

On contrast Prototypal Inheritance means?

If you have scope hierarchy, then parent scope property are accessible inside child scope, only if those property are object (originally object referenced is passed to child scope without creating its new reference). But primitive datatypes are not accessible inside child scope and if you looked at your code addCustom scope variable is of primitive dataType.


Lets discuss more about it.

Here you have myController controller which has addCustom scope variable of primitive type & as I said above ng-switch & ng-if directive are compiled they do create new child scope on that element. So in your current markup you have ng-switch on ng-controller="myController" div itself. For inner html it had created a child scope. If you wanted to access parent scope inside child(primitive type) you could use $parent notation before scope variable name. Now you can access the addCustom value by $parent.addCustom. Here its not over when angular compiler comes to ng-if div, it does create new child scope again. Now inner container of ng-if will again have child scope which is prototypically inherited from parent. Unfortunately in your case you had primitive dataType variable so you need to use $parent notation again. So inside ng-if div you could access addCustom by doing $parent.$parent.addCustom. This $parent thing will solve your problem, but having it on HTML will make unreadable and tightly couple to its parent scope(suppose on UI you would have 5 child scope then it will look so horrible like $parent.$parent.$parent.$parent). So rather you should go for below approach.


Follow Dot rule while defining ng-model

So I'd say that you need to create some object like $scope.model = {} and add addCustom property to it. So that it will follow the prototypal inheritance principle and child scope will use same object which have been created by parent.

angular.module('myApp')
.controller('myController',['$scope',myController]);
 function myController($scope){ 
    $scope.model = { addCustom : false };
}

And on HTML you will use model.addCustom instead of addCustom

Markup

<div ng-controller="myController" ng-switch on="addressCards">
    <div>
        {{model.addCustom}} // does not get changed
        <div ng-if="model.addCustom === false">

            {{model.addCustom}} // does get changed
            <button type="button" class="btn btn-primary btn-icon-text" ng-click="model.addCustom = true">
                <span class="icon icon-plus"></span>
                click here
            </button>
        </div>
    </div>
</div>

Other best way to deal with such kind of issue is, use controllerAs pattern while using controller on HTML.

Markup

<div ng-controller="myController as myCtrl" ng-switch on="addressCards">
    <div>
        {{myCtrl.addCustom}} // does not get changed
        <div ng-if="myCtrl.addCustom === false">

            {{myCtrl.addCustom}} // does get changed
            <button type="button" class="btn btn-primary btn-icon-text" ng-click="myCtrl.addCustom = true">
                <span class="icon icon-plus"></span>
                click here
            </button>
        </div>
    </div>
</div>

这篇关于Angular - 改变范围没有得到反映的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆