【问题标题】:Update a service value from a parent controller从父控制器更新服务值
【发布时间】:2015-11-19 10:49:30
【问题描述】:

我一直在寻找如何从嵌套控制器更新服务值的几个小时。
我的子控制器需要更新服务中的值。并且该值需要显示在父控制器中。

我制作了一个 jsfiddle 以使其更加清晰和易于帮助 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();
});

(我已阅读并尝试过Update parent scope variable,但无法使其与该服务一起使用。)

谢谢!

【问题讨论】:

  • 您发布的链接显示基本相同的问题。如果您尝试在那里实施解决方案但失败了,请向我们展示您根据该答案尝试的代码!

标签: javascript angularjs


【解决方案1】:

使用对象字面量代替变量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>

【讨论】:

    【解决方案2】:

    使服务中的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>

    【讨论】:

    • 同样的小提琴。我认为你需要分叉。
    • 对不起.. 小提琴被替换了
    【解决方案3】:

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

    $scope.username = authenticationSrv.getUser();
    

    user复制$scope.username。因此,仅仅因为稍后您在服务中覆盖了 user 的值,您的“父”$scope 中没有任何变化。

    有几种方法可以解决这个问题,最简单的可能是在您的服务中创建一个用户 object - 如果您将对该对象的引用存储在您的范围中,它将反映所做的更改从其他控制器到它。 (javascript 中的对象是通过引用值传递的,所以所有控制器都会影响同一个对象,而不是值的副本。)对于实际实现,我会引导你回到 same link you posted - 当你尝试实施它,有什么问题?向我们展示您尝试过的代码。

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

    【讨论】:

      【解决方案4】:

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

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

      在子范围内你刚刚设置它:

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

      这是Fiddle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-17
        • 2013-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多