从父控制器更新服务值

Update a service value from a parent controller

本文关键字:服务 更新 控制器      更新时间:2023-09-26

我已经搜索了几个小时如何从嵌套控制器更新服务值。
我的子控制器需要更新服务中的值。这个值需要显示在父控制器中

我做了一个简单的说明,使它更清楚,更容易帮助http://jsfiddle.net/jtsmduxw/3/

<body ng-app="MyApp">
    <div ng-controller="parentCtrl">
        <p>{{username}}</p>
        <div ng-controller="childCtrl">
            <p>{{username}}</p>
        </div>
    </div>
</body>

var app = angular.module("MyApp", []);
app.service('authenticationSrv', function () {
    var user = 'anonymous';
    return {
        getUser: function () {
            return user;
        },
        setUser: function (value) {
            user = value;
        }
    };
});
app.controller("parentCtrl", function ($scope, authenticationSrv) {
    $scope.username = authenticationSrv.getUser();
});
app.controller("childCtrl", function ($scope, authenticationSrv) {
    authenticationSrv.setUser('my name'); // I need this function to also update the scope of the parent
    $scope.username = authenticationSrv.getUser();
});

(我已经阅读并尝试更新父作用域变量,但我无法使它与服务一起工作。)

谢谢!

使用对象字面值代替变量username

父母

app.controller("parentCtrl", function ($scope, authenticationSrv) {
    $scope.parentObject = {};
    $scope.parentObject.username = authenticationSrv.getUser();
});

app.controller("childCtrl", function ($scope, authenticationSrv) {
    authenticationSrv.setUser('my name'); 
    $scope.parentObject.username = authenticationSrv.getUser();
});

工作示例

var app = angular.module("MyApp", []);
app.service('authenticationSrv', function () {
    var user = 'anonymous';
    return {
        getUser: function () {
            return user;
        },
        setUser: function (value) {
            user = value;
        }
    };
});
app.controller("parentCtrl", function ($scope, authenticationSrv) {
    $scope.parentObject = {};
    $scope.parentObject.username = authenticationSrv.getUser();
});
app.controller("childCtrl", function ($scope, authenticationSrv) {
    authenticationSrv.setUser('my name'); 
    $scope.parentObject.username = authenticationSrv.getUser();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="MyApp">
    <div ng-controller="parentCtrl">
        <p>{{parentObject.username}}</p>
        <div ng-controller="childCtrl">
            <p>{{parentObject.username}}</p>
        </div>
    </div>
</body>

使服务中的user成为对象而不是原语(字符串)。然后在视图中使用{{user.name}}

注意,我对authenticationSrv.setUser()做了一些小的改变并重命名为authenticationSrv.setUserName()

查看我的工作小提琴:https://jsfiddle.net/rbwk3rqb/

var app = angular.module("MyApp", []);
angular.module("MyApp")
.service('authenticationSrv', function () {
    var user = {name: 'anonymous'};
    return {
        getUser: function () {
            return user;
        },
        setUserName: function (value) {
            user.name = value;
        }
    };
});
angular.module("MyApp")
.controller("parentCtrl", function ($scope, authenticationSrv) {
    $scope.user = authenticationSrv.getUser();
});
angular.module("MyApp")
.controller("childCtrl", function ($scope, authenticationSrv) {
    authenticationSrv.setUserName('my name');
    $scope.user = authenticationSrv.getUser();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="MyApp">
    <div ng-controller="parentCtrl">
        <p>{{user.name}}</p>
        <div ng-controller="childCtrl">
            <p>{{user.name}}</p>
        </div>
    </div>
</body>

由于user是服务中的原始值,因此当您使用以下行将服务中的值放入控制器的作用域时:

$scope.username = authenticationSrv.getUser();
user复制到$scope.username中。因此,仅仅因为稍后您在服务中覆盖了user的值,在"父"$作用域中没有任何变化。 有几种方法可以解决这个问题,最简单的方法可能是在你的服务中创建一个user 对象——如果你在你的作用域中存储了对这个对象的引用,它将反映其他控制器对它所做的更改。(javascript中的对象是通过引用值传递的,所以所有控制器都会影响相同的对象,而不是值的副本)对于实际实现,我会引导你回到你发布的相同链接-当你尝试实现它时,它的问题是什么?给我们看看你试过的代码

或者,你也可以使用这个服务来实现观察者模式(这是相当多的工作),或者使用作用域层次结构上的事件来通知控制器用户的变化(这是一个有问题的做法)。

这个想法是创建一个要更新的对象,而不仅仅是一个原语:

$scope.user = {};
$scope.user.name = authenticateSrv.getUser();

在子作用域中你只需要设置它:

$scope.user.name = authenticateSrv.setUser('my name');

这里是一个提琴