【问题标题】:How to update another angular controller in real-time using controllerAs syntax如何使用 controllerAs 语法实时更新另一个角度控制器
【发布时间】:2015-09-24 22:40:26
【问题描述】:

我目前正在尝试使用来自一个控制器的服务从 Web API 检索行计数值,然后在从数据库中检索到该值后更新另一个控制器的变量 - 同时避免使用 $scope 或 $根范围。

下面是Controller1 - 当服务中的值发生变化时,这个控制器需要更新它的变量。目前它运行正常,但我想避免使用 $scope 或 $rootScope:

(function() {
'use strict';

angular
    .module('app.event')
    .controller('Controller1', Controller1);
Controller1.$inject = ['service1', '$stateParams', '$rootScope'];

/**
 * Controller 1
 * @constructor
 */
function Controller1(service1, $stateParams, $rootScope) {
    // Declare self and variables
    var vm = this;
    vm.number = 0;

    init();

    $rootScope.$on('countChanged', refresh);

    /**
     * Initializes the controller
     */
    function init() {
        service1.refreshCount($stateParams.id);
    }

    /**
     * Refreshes the count
     * @param {object} event - The event returned from the broadcast
     * @param {int} count - The new count to update to
     */
    function refresh(event, count) {
        vm.number = count;
    }
}
})();

服务 - 我想避免在这里使用 $rootScope.$broadcast:

(function() {
'use strict';

angular
    .module('app.event')
    .factory('service1', service1);

service1.$inject = ['APP_URLS', '$http', '$rootScope'];

/**
 * The service
 * @constructor
 */
function service1(APP_URLS, $http, $rootScope) {
    // Declare
    var count = 0;

    // Create the service object with functions in it
    var service = {
        getCount: getCount,
        setCount: setCount,
        refreshCount: refreshCount
    };

    return service;

    ///////////////
    // Functions //
    ///////////////

    /**
     * Re-calls the web API and updates the count
     * @param {Guid} id - The ID needed for the API call parameter
     */
    function refreshCount(id) {
        $http({ url: APP_URLS.api + '<TheAPINameHere>/' + id, method: 'GET' }).then(function (response) {
            setCount(response.data.Count);
            changed();
        });
    }

    /**
     * Returns the count value
     */
    function getCount() {
        return count;
    }

    /**
     * Re-calls the web API and updates the count
     * @param {int} newCount - The new count value
     */
    function setCount(newCount) {
        count = newCount;
        changed();
    }

    /**
     * Broadcasts a change event to be picked up on in Controller1
     */
    function changed() {
        $rootScope.$broadcast('countChanged', count);
    }
}
})();

以下是 Controller2 中的一个函数,用于更新服务中的值 - 我希望能够在执行此操作后立即更新 Controller1 中的值:

/**
 * Removes a row from the database
 * @param {object} field - The data row object that we're deleting from the table
 */
function remove(field) {
    // Delete the row from the database
    service2.delete(field.Id);

    // Remove the row from the local data array and refresh the grid
    vm.data.splice(vm.data.indexOf(field), 1);

    // Set the count in the service to update elsewhere
    service1.setCount(vm.data.length);
    vm.indices.reload();
}

【问题讨论】:

  • 我认为你的做法是错误的。你想要是你的服务上可以直接绑定的公共属性。但是,您在此处使用的模式是服务上的 private 属性,具有无法直接绑定的 getter 和 setter。
  • 最简单的......使count成为服务对象的属性
  • 如上所说,将其设为可通过 $watch 观察的公共道具或实现 pub sub 机制。只是好奇,为什么不喜欢 $broadcast?
  • 旁注,使用$rootscope 还不错,这是一个问题滥用 $rootscope。将其用于广播是完全可以接受的,而将其用于保存值是一种代码味道。
  • 我还想指出,您可以通过调用 $rootScope.emit 来限制广播的范围。这将从范围而不是从根一直向下传播。在您从根范围发出的地方,只有其他根范围侦听器会收到通知。

标签: javascript angularjs controlleras


【解决方案1】:

我避免将 $rootScope 用于练习目的,但这似乎是最好的方法。当我尝试按照其他一些建议使用公共属性时,它对我不起作用,所以我像 CainBot 建议的那样使用 $rootScope.$emit。

【讨论】:

    猜你喜欢
    • 2014-01-03
    • 1970-01-01
    • 2013-01-17
    • 2016-04-18
    • 1970-01-01
    • 2022-11-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多