javascript - AngularJS : How do I properly set a service property from model data in a controller?

标签 javascript angularjs angularjs-scope angularjs-service angularjs-controller

我已经设置了一项服务来在多个 Controller 之间共享一些数据/状态。在一个 Controller 中,我通过保存函数使用范围数据更新一些服务属性。然后,通过为服务分配范围值,在其他 Controller 中使用该数据。问题是,根据第一个 Controller 分配给服务的数据类型,它们的行为是不同的。如果模型数据是原始值,则只有在运行保存函数时才会更新服务的属性。然而,如果模型数据是一个对象,它会随着模型数据的改变而不断更新服务。我正在寻找实现“保存”功能,所以这不是我想要的。

所以我试图理解不同的行为:原始与对象,以及为什么对象立即更新,以及使用对象实现保存功能的正确方法是什么。我知道您可以使用事件,我可以在 $rootScope 上使用 $broadcast 和事件,并在第二个 Controller 上使用该事件将服务属性分配给作用域变量,但我喜欢将服务分配给作用域的简单性第二个 Controller ,如果可能的话希望使用该方法。

这是一个简化的示例。

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

myApp.service('myService', function () {
    this.text = '';
    this.objText = {};

    this.setText = function (text) {
        this.text = text;
    };

    this.setObjText = function (obj) {
        this.objText = obj;
    };
});

myApp.controller('InputCtrl', ['$scope', 'myService', function ($scope, myService) {
    $scope.textObj = {};
    $scope.saveText = function (text) {
        myService.setText(text);
    }
    $scope.saveObj = function (obj) {
        myService.setObjText(obj);
    }
}]);

myApp.controller('OutputCtrl', ['$scope', 'myService', function ($scope, myService) {
    $scope.myService = myService;
}]);

在 View 中(部分):

<div ng-controller="OutputCtrl">
    <strong>Text:</strong> {{ myService.text }}<br>
    <strong>Obj Text:</strong> {{ myService.objText }
</div>

在这里完成 fiddle :http://jsfiddle.net/anpsince83/uRH93/2/

最佳答案

这与 Angular 无关。它是简单的、古老的 JavaScript 相关的。

在你的 fiddle HTML 中(下面的数字仅供引用):

(1)<input type="text" ng-model="text1">
(2)<button ng-click="saveText(text1)">Save Text</button>
   ...
(3)<input type="text" ng-model="textObj.text1">
(4)<input type="text" ng-model="textObj.text2">
(5)<button ng-click="saveObj(textObj)">Save Object Text</button>

“字符串”情况(原始):

第 (1) 行创建一个字符串变量,名为 text1 ,在 InputCtrl 的作用域(以下称为 inScope)中,并将其绑定(bind)到输入字段的值。每当输入字段的值发生变化时,inScope.text1 的值也会发生变化。 .
单击按钮(第 (2) 行)时,myService 的 text变量设置为 inScope.text1 。因为 'string' 是一个原语,所以它是按值传递的,这意味着 myService.textinScope.text1 引用同一个对象 - 它们只是“碰巧”在 saveText() 之后具有相同的值方法被调用。一次inScope.text1更改(例如,用户在输入字段中键入内容),myService.text对此一无所知。这种情况相当于:

var a = 'value1';
var b = a;
// Now: a === 'value1', b === 'value1'

a = 'value2';
// Now: a === 'value2', b === 'value1'

“对象”案例(对象):

第 (3) 行和第 (4) 行在 inScope 的 text1 引用的(最初为空)对象中创建两个属性( text2textObj )。多变的。每当每个输入字段的值发生变化时, inScope.textObj 引用的对象的相应属性的值也会发生变化。 .
单击按钮(第 (5) 行)时,myService 的 object变量设置为引用inScope.textObj 相同的对象。您注意到我使用术语引用而不是。因为“object”不是基元,所以它是通过引用传递的,这意味着 myService.objectinScope.textObj引用相同对象(在调用 saveObj() 方法之后。更改第 (2) 行和第 (3) 行中定义的输入字段的值会影响inScope.textObj 引用的对象(也被 myService.object 引用)。这种情况相当于:

var a = { key: 'value1' };   // Creates new object, say {obj1}
var b = a;                   // Now b references {obj1} as well
// Now: a.key === 'value1', b.key === 'value1'

a.key = 'value2';   // Changes {obj1}'s key's value
                    // but {obj1} is also referenced by b, so...
// Now: a.key === 'value2', b.key === 'value2'

// This does not happen in your code, so you never lose reference to
// the same object from both `myService.object` and `inScope.textObj`
a = { key: 'value3' };   // Creates new object, say {obj2}
                         // but b still references {obj1}, not {obj2}, so...
// Now: a.key === 'value3', b.key = 'value2'

<强> More info JS 基元与对象

关于javascript - AngularJS : How do I properly set a service property from model data in a controller?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21199186/

相关文章:

javascript - 将用户输入的输入数字限制为 4 位

javascript - 将单个键盘快捷键分配给 Web 表单上的单选按钮

angularjs - 使用 Office 365 API AngularJS 打开文档文件

angularjs - 在 ng Select 中设置默认值

javascript - 将 JSTL 值从列表中提取到 javascript 变量中

javascript - 如何在单击一个链接按钮时调用 javascript 和代码隐藏函数?

javascript - Jquery - 获取一行的所有内容

javascript - 在 if 语句中使用 return 速记不起作用

angularjs - 如何获取 Controller 中数组项的索引位置并在angularjs中传递值

javascript - ng-class 在 AngularJS 中不起作用