简体   繁体   English

Angularjs:ngDialog只与对象绑定和修改; 不是基本变量。

[英]Angularjs: ngDialog only binds and modifies with objects; not basic variables.

I've already found a "solution" to this problem; 我已经找到了解决这个问题的“解决方案”; I was just hoping someone might be able to provide a reason why it works. 我只是希望有人能够提供其工作原因。

This jsFiddle demonstrates the problem: http://jsfiddle.net/s1ca0h9x/137/ 这个jsFiddle演示了这个问题: http//jsfiddle.net/s1ca0h9x/137/

HTML HTML

<div data-ng-app="myApplication">
    <div data-ng-controller="MainController">
<a href="" ng-click="ShowNgDialog()">Click Here</a>

        <input type="text" ng-model="accountNum" />
        <span>{{accountNum}}</span>

    </div>
</div>

ANGULARJS ANGULARJS

var myApplication = angular.module('myApplication', ['ngDialog']);

myApplication.controller('MainController', function ($scope, ngDialog) {
    $scope.accountNum = 'test';
    $scope.ShowNgDialog = function () {
        ngDialog.open({            
            template: '<div><input type="text" ng-model="accountNum"/></div>',
            plain: true,
            scope:$scope

        });
    }    
});

When I try and manipulate a scope variable (in this case: $scope.accountNum = 'test') from the dialog, it doesn't bind/save it back to the model. 当我尝试从对话框中操作范围变量 (在这种情况下:$ scope.accountNum ='test')时,它不会将其绑定/保存回模型。

...However, when I change that variable into an object, things just magically work, as shown in this demo: http://jsfiddle.net/s1ca0h9x/138/ ...但是,当我将该变量更改为一个对象时,事情就会神奇地起作用,如本演示所示: http//jsfiddle.net/s1ca0h9x/138/

HTML HTML

<div data-ng-app="myApplication">
    <div data-ng-controller="MainController">
<a href="" ng-click="ShowNgDialog()">Click Here</a>

        <input type="text" ng-model="FormData.accountNum" />
        <span>{{FormData.accountNum}}</span>

    </div>
</div>

ANGULARJS ANGULARJS

var myApplication = angular.module('myApplication', ['ngDialog']);

myApplication.controller('MainController', function ($scope, ngDialog) {
    $scope.FormData={accountNum: ''};
    $scope.ShowNgDialog = function () {
        ngDialog.open({            
            template: '<div><input type="text" ng-model="FormData.accountNum"/></div>',
            plain: true,
            scope:$scope

        });
    }    
});

I also tested both options using a template linking to a file, and not using plain:true, in addition to trying ngDialog.openConfirm, etc. I essentially rebuilt the solution found here ngDialog $scope variables not being updated by ngModel fields in $dialog when using scope: $scope piece by piece, and finally the only change that seemed to work was using an object instead of a basic scope variable. 我还使用链接到文件的模板测试了两个选项,而不是使用plain:true,除了尝试ngDialog.openConfirm等。我基本上重建了这里找到的解决方案ngDialog $ scope变量没有被$ dialog中的ngModel字段更新当使用范围:$ scope一块一块,最后唯一似乎工作的变化是使用对象而不是基本范围变量。 Am I approaching this wrong, or missing some fundamental aspects of data binding? 我是在接近这个错误,还是遗漏了数据绑定的一些基本方面?

I think this has nothing to do with the binding. 我认为这与绑定无关。 I will explain what I did understood when I dig into the code of ngDialog and AngularJS . 当我深入研究ngDialogAngularJS的代码时,我将解释我所理解的内容

I think the first case is not working as you expect, because $scope.accountNum = 'test'; 我认为第一种情况并不像你期望的那样工作,因为$scope.accountNum = 'test'; is a simple string which is a primitive type and is not mutable ( ref ) or in other words is immutable : 是一个简单的字符串,它是一个原始类型, 不是可变的ref )或换句话说是不可变的

Mutable is a type of variable that can be changed. Mutable是一种可以改变的变量。 In JavaScript, only objects and arrays are mutable, not primitive values . 在JavaScript中,只有对象和数组是可变的, 而不是原始值 ( You can make a variable name point to a new value, but the previous value is still held in memory. Hence the need for garbage collection. ) 您可以将变量名称指向新值,但之前的值仍保留在内存中。因此需要进行垃圾回收。

A mutable object is an object whose state can be modified after it is created . 可变对象是一个对象,其状态可以在创建后进行修改

Immutables are the objects whose state cannot be changed once the object is created. 不可变一旦创建对象就无法更改其状态的对象。

String and Numbers are Immutable. 字符串和数字是不可变的。

So, in short words, this was the reason why the first variant is not working as you want :) 所以,简而言之,这就是为什么第一个变体不能按你的意愿工作的原因:)


Now let's have a look on this code of ngDialog, which is a part of open() method: 现在让我们来看看这个 ngDialog代码,它是open()方法的一部分:

var scope;
scopes[dialogID] = scope = angular.isObject(options.scope) ? options.scope.$new() : $rootScope.$new();

in your case we are calling options.scope.$new() , because you specified scope in options when opening the dialog. 在您的情况下,我们调用options.scope.$new() ,因为您在打开对话框时在选项中指定了scope

Now let's go and check this angular code: 现在我们去检查这个角度代码:

$new: function (isolate, parent) {
    var child;  
    parent = parent || this;

    if (isolate) {
        child = new Scope();
        child.$root = this.$root;
    } else {
        if (!this.$$ChildScope) {
            this.$$ChildScope = createChildScopeClass(this); // <---- WE ARE COMING HERE NOW
        }
        child = new this.$$ChildScope();
    }
    ...

function createChildScopeClass looks like: 函数createChildScopeClass看起来像:

function createChildScopeClass(parent) {
    function ChildScope() {
        this.$$watchers = this.$$nextSibling =
                this.$$childHead = this.$$childTail = null;
        this.$$listeners = {};
        this.$$listenerCount = {};
        this.$$watchersCount = 0;
        this.$id = nextUid();
        this.$$ChildScope = null;
    }
    ChildScope.prototype = parent; /* <--- They simply assign the derived scope 
     as prototype of the new one (which is going to be the scope of the ngDialog) */
    return ChildScope;
}

We can see that function createChildScopeClass() simply assigns the parent scope's prototype to the new one ( which is going to be the scope of the opened ngDialog ) 我们可以看到function createChildScopeClass()只是将父作用域的原型分配给新作用域( 这将是打开的ngDialog的作用域

And a sample that is demonstrating mutability and immutability: 一个展示可变性和不变性的样本:

 var test = 'test'; var test2 = test; test2 = 'new value'; console.log('test = ' + test + ' // test2 = ' + test2); var testObj = {test: 'test'}; var test2Obj = testObj; test2Obj.test = 'new value'; console.log('testObj.test = ' + testObj.test + ' // test2Obj.test = ' + test2Obj.test); 

Conclusion 结论

Use objects or arrays in your parent scope if you want binding to work in the derived scope. 如果希望绑定在派生范围内工作,请在父范围中使用对象数组 Sample using AngularJS: 使用AngularJS的示例:

 var app = angular.module('sample', []); app.controller('AppController', ['$scope', function($scope) { $scope.primitive = 'test'; $scope.obj = { test: 'test initial' }; $scope.newScope = $scope.$new(); $scope.newScope.primitive = 'test 2'; $scope.newScope.obj.test = 'updated value'; }]); app.run(); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="sample"> <div ng-controller="AppController"> <table> <thead><tr><th>Property</th><th>Value</th><th></th></tr></thead> <tbody> <tr> <td>primitive</td> <td>{{ primitive }}</td> <td><input type="text" ng-model="primitive"></td> </tr> <tr> <td>obj.test</td> <td>{{ obj.test }}</td> <td><input type="text" ng-model="obj.test"></td> </tr> <tr> <td>newScope.primitive</td> <td>{{ newScope.primitive }}</td> <td><input type="text" ng-model="newScope.primitive"></td> </tr> <tr> <td>newScope.obj.test</td> <td>{{ newScope.obj.test }}</td> <td><input type="text" ng-model="newScope.obj.test"></td> </tr> </tbody> </table> </div> </div> 

For me what worked, is to create a function in the base controller, and call the function from ngDialog controller. 对我来说有用的是在基本控制器中创建一个函数,并从ngDialog控制器调用该函数。

Ex: 例如:

myApplication.controller('MainController', function ($scope, ngDialog) {
    $scope.accountNum = 'test';
    $scope.ShowNgDialog = function () {
        ngDialog.open({            
            template: '<div><input type="text" ng-model="accountNum"/></div>',
            plain: true,
            scope:$scope,
            controller: ['$scope',
                function ($scope) {
                    $scope.updateVar();
                }]
        });
    };

    $scope.updateVar = function(){
        $scope.accountNum = "changed";
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM