AngularJS ui-router更新父控制器模型

时间:2015-05-06 21:23:33

标签: angularjs angular-ui-router

所以我设置了这些状态:

// Now set up the states
$stateProvider.state('collections', {
    url: '/collections/:centerId',
    templateUrl: '/assets/tpl/collections/index.html',
    controller: 'CollectionsController',
    controllerAs: 'controller',
    resolve: {

        // Resolve our collections before the state loads
        collections: ['$stateParams', 'Api', function ($stateParams, api) {

            // Get our center id
            var centerId = $stateParams.centerId;

            // Return our collections
            return api.get('/api/collections', { centerId: centerId });
        }]
    },
    data: {
        requireLogin: true,
        pageTitle: 'Collections'
    }
}).state('collections.import', {
    url: '/import',
    templateUrl: '/assets/tpl/collections/import.html',
    controller: 'ImportCollectionsController',
    controllerAs: 'controller',
    data: {
        requireLogin: true,
        pageTitle: 'Import your collections'
    }
});

如果您查看2个州,可以看到在父状态下我从API解析了所有当前的集合。然后将其分配给 CollectionsController 范围(this.collections)。 在 ImportCollectionsController 中,我可以通过 $ scope 访问该数据:

.controller('CollectionsController', ['$stateParams', 'collections', function ($stateParams, collections) {

    // Assign this to a variable
    var self = this;

    // Get our collections
    self.collections = collections;

    /// --- removed for brevity --- ///
}])

.controller('ImportCollectionsController', ['$stateParams', '$scope', 'CollectionsService', 'toastr', function ($stateParams, $scope, collections, toastr) {

    // Assign this to a variable
    var self = this;

    // Get our center id
    self.centerId = $stateParams.centerId;

    /// --- removed for brevity --- ///

    // Save our data
    self.save = function () {

        // Import our results into our collections
        self.import = collections.import(self.centerId, self.results);

        // If the import is successful
        self.import.promise.then(function (response) {

            // Get our original collection array
            var originals = $scope.$parent.controller.collections.data

            // Update our original collection with the new imported items
            originals.push(response.data);

            // Set our results to nothing
            self.results = null;

            // Display a success message
            toastr.success('Your collections have been imported successfully.');
        });
    };
}])

只是你需要它,这是我的API服务:

.service('Api', ['$http', 'HttpHandler', function ($http, handler) {

    // Private function to build our request
    var buildRequest = function (url, method, data, params) {
        var model = {
            method: method,
            url: url,
            data: data,
            params: params
        };

        return $http(model);
    };

    // GET
    this.get = function (url, params) {
        return handler.loadData(buildRequest(url, 'GET', null, params));
    };

    // POST
    this.post = function (url, data) {
        return handler.loadData(buildRequest(url, 'POST', data));
    };

    // PUT
    this.put = function (url, data) {
        return handler.loadData(buildRequest(url, 'PUT', data));
    };

    // DELETE
    this.delete = function (url, data) {
        return handler.loadData(buildRequest(url, 'DELETE', data));
    };
}])

.service('HttpHandler', ['ErrorService', function (service) {

    // Function to handle promises
    this.loadData = function (promise) {

        // Declare our model
        var model = {
            data: null,
            loading: true,
            promise: promise,
            error: null
        };

        // If our promise succeeds
        promise.then(function (response) {

            // Store the data
            model.data = response.data.result || response.data;
        }, function (error) {

            // Process our error
            model.error = service.process(error);
        });

        // Finally
        promise.finally(function () {

            // Set our loading flag to false regardless if there is an error or not
            model.loading = false;
        });

        // Return our model
        return model;
    };
}])

理论上,当我在 ImportCollectionsController 中调用 save 函数时,如果承诺成功,我将数组添加到现有数组中。我期望的是,如果我回到集合状态,我现在应该看到我的新数据,但我不知道。 谁能告诉我为什么?

更新

所以我已将状态更改为此(请注意解决方案)

.config(['$stateProvider', function ($stateProvider) {

    // Now set up the states
    $stateProvider.state('collections', {
        url: '/collections/:centerId',
        templateUrl: '/assets/tpl/collections/index.html',
        controller: 'CollectionsController',
        controllerAs: 'controller',
        resolve: {

            // Resolve our collections before the state loads
            collections: ['$stateParams', 'Api', function ($stateParams, api) {

                // Get our center id
                var centerId = $stateParams.centerId;

                // Return our collections
                return api.get('/api/collections', { centerId: centerId });
            }]
        },
        data: {
            requireLogin: true,
            pageTitle: 'Collections'
        }
    }).state('collections.import', {
        url: '/import',
        templateUrl: '/assets/tpl/collections/import.html',
        controller: 'ImportCollectionsController',
        controllerAs: 'controller',
        resolve: {
            originals : ['collections', function (collections) {
                return collections.data;
            }]
        },
        data: {
            requireLogin: true,
            pageTitle: 'Import your collections'
        }
    }).state('collections.create', {
        url: '/create',
        templateUrl: '/assets/tpl/collections/save.html',
        controller: 'SaveCollectionController',
        controllerAs: 'controller',
        data: {
            requireLogin: true,
            pageTitle: 'Save your collection'
        }
    });
}])

并在我的 ImportCollectionsController 中我将保存功能更改为:

.controller('CollectionsController', ['$stateParams', 'collections', function ($stateParams, collections) {

    // Assign this to a variable
    var self = this;

    // Get our collections
    self.collections = collections;

    console.log(self.collections);
}])

.controller('ImportCollectionsController', ['$stateParams', 'originals', 'CollectionsService', 'toastr', function ($stateParams, originals, collections, toastr) {

    // Assign this to a variable
    var self = this;

    // Get our center id
    self.centerId = $stateParams.centerId;

    // Save our data
    self.save = function () {

        // Import our results into our collections
        self.import = collections.import(self.centerId, self.results);

        // If the import is successful
        self.import.promise.then(function (response) {

            // Update our original collection with the new imported items
            originals.push(response.data);

            // Set our results to nothing
            self.results = null;

            // Display a success message
            toastr.success('Your collections have been imported successfully.');
        });
    };

    // Cancel our import
    self.cancel = function () {

        // Set our results to nothing
        self.results = null;
    }
}])

我仍然遇到同样的问题。当我导航回集合时,它们未列出。

1 个答案:

答案 0 :(得分:0)

好的,为了解决这个问题,我改变了我的状态:

.config(['$stateProvider', function ($stateProvider) {

    // Now set up the states
    $stateProvider.state('collections', {
        url: '/collections/:centerId',
        templateUrl: '/assets/tpl/collections/index.html',
        controller: 'CollectionsController',
        controllerAs: 'controller',
        resolve: {

            // Resolve our collections before the state loads
            collections: ['$stateParams', 'Api', function ($stateParams, api) {

                // Get our center id
                var centerId = $stateParams.centerId;

                // Return our collections
                return api.get('/api/collections', { centerId: centerId });
            }]
        },
        data: {
            requireLogin: true,
            pageTitle: 'Collections'
        }
    }).state('collections.import', {
        url: '/import',
        templateUrl: '/assets/tpl/collections/import.html',
        controller: 'ImportCollectionsController',
        controllerAs: 'controller',
        data: {
            requireLogin: true,
            pageTitle: 'Import your collections'
        }
    }).state('collections.create', {
        url: '/create',
        templateUrl: '/assets/tpl/collections/save.html',
        controller: 'SaveCollectionController',
        controllerAs: 'controller',
        data: {
            requireLogin: true,
            pageTitle: 'Save your collection'
        }
    });
}])

不需要在子状态上创建单独的解析,因为它们从父级继承。

考虑到这一点,我可以将 ImportCollectionsController 更改为:

.controller('ImportCollectionsController', ['$stateParams', 'collections', 'CollectionsService', 'toastr', function ($stateParams, originals, collections, toastr) {

    // Assign this to a variable
    var self = this;

    // Get our center id
    self.centerId = $stateParams.centerId;

    // Save our data
    self.save = function () {

        // Import our results into our collections
        self.import = collections.import(self.centerId, self.results);

        // If the import is successful
        self.import.promise.then(function (response) {

            // Update our original collection with the new imported items
            for (var i = 0; i < response.data.length; i++)
                originals.data.push(response.data[i]);

            // Set our results to nothing
            self.results = null;

            // Display a success message
            toastr.success('Your collections have been imported successfully.');
        });
    };

    // Cancel our import
    self.cancel = function () {

        // Set our results to nothing
        self.results = null;
    }
}])

这解决了这个问题。