AngularJs在整个应用程序

时间:2015-12-21 15:30:56

标签: angularjs

我正在AngularJs制作应用程序,我面临的情况是我需要在多个视图中调用相同的函数。

在这种情况下,它是一个商店系统,在多个视图中可以看到同一商店。在家中,如果它靠近用户,付费广告,搜索结果等。

我知道这个功能应该是我已经做过的服务。但问题是:我应该如何从view / html调用此函数?

我想避免在多个控制器中反复重新定义相同的调用,但直到现在,还没有找到与此特定问题相关的任何内容。

这是我的代码:

function mainFactory($http) {
    var service = {
        addFav: _addFav
    };
    return service;

    function _addFav(data, func) {
        return $http.post(baseUrl+func,data).then( 
            function(res) {return res.data;},
            function(err) {alert(_errorMsg);}
        );
    };
}

function HomeController() {
    vm.addFavorites = addFavorites;
    function addFavorites(data) {
        var func = 'function_name';
        mainFactory.addFav(data,func);
    }
}

function AdvController() {
    vm.addFavorites = addFavorites;
    function addFavorites(data) {
        var func = 'function_name';
        mainFactory.addFav(data,func);
    }
}

function SearchController() {
    vm.addFavorites = addFavorites;
    function addFavorites(data) {
        var func = 'function_name';
        mainFactory.addFav(data,func);
    }
}

如您所见,我需要在多个控制器中调用相同的功能。

我已经看到一些其他的例子说使用这个函数作为.run的$ rootScope函数,但也有更多的内容警告,不能将函数定义为根函数。

关于如何解决这个问题的任何建议?

编辑:

我现在正在使用的其他解决方案是通过指令在body标签中定义'MainController',所以我可以在整个应用程序中使用此函数。但是这个控制器正在通过很多功能/过程来复杂维护。

2 个答案:

答案 0 :(得分:4)

  

我应该如何从view / html调用此函数?

您不应该直接从视图中进行操作。

但是,您可以将控制器嵌套到其他控制器中。所以,如果你认为你的功能应该是一个“特殊的”,你可以有以下“场景”。

html:

<div ng-controller="appController as app">
    <div ng-controller="HomeController as home"> 
         <button ng-click="app.addFavorites();"></button>
    </div>

    <!-- ... -->
</div>

如果您将appController远离“内部视图”,这也适用于SPA。随意给这个“appController”另一个名字(我觉得很糟糕)。

答案 1 :(得分:0)

假设你有这样的应用程序:

<html ng-app="app">

<body ng-controller="MainController">

<div ui-view></div>

</body>
</html>

然后你有app:

angular.module('app', ['app.models']).controller('MainController', MainController);

function MainController($scope, MyService) {

    $scope.addToFav = function (data) {

        // suppose data is object
        // then 

        MyService.add({
           url: "...",
           data: data
        }).then(function(result) {

             // success

        }).catch(function(error) {

            // wrong

        });
    }
}

// this is a service, shared by controller
(function (angular) {

    'use strict';

    angular.module('app.models')
        .factory("MyService", _model);

    _model.$injector = ['$http'];

    function _model($http) {

        var service = {
            all: all,
            one: one,
            update: update,
            add: add,
            remove: remove
        };

        return service;

       function add(param) {

            var url = param.url;

            if (url === null) {
                return null;
            }

    $http({
        url: url,
        method: 'POST',
        data: $httpParamSerializerJQLike(param.data),
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
       }).then(function (result) {
                return result;
       });
    }
})(angular);

然后您可以在任何控制器中使用MyService,并且可以将addToFav用于同一个应用中的任何视图...

<a ng-click="addToFav(...)"></a>

如果您担心MainController的膨胀问题,更好的方法是使用本地控制器作为vm:

function ExampleController($scope, Product) {

  var vm = this;

  vm.product = ProductComponent.singleton($scope, Product)

}

var ProductComponet = (function () {

    var instance;
    var scope;

    return {
        singleton: function (_scope, Model) {

            scope = _scope;

            if (!instance) {
                instance = createInstance(Model);
                console.log(instance);
            }

            console.log(instance);

            return instance;
        }
    };

    function createInstance( Model) {

       var vm = {
         item: {},
         list: [],
         addToFav: addToFav
       };

       return vm;

       function addToFav() {

       }
    }
})();

然后在您看来,您可以使用:

vm.product.item访问当前项目

vm.product.list访问所有项目

将所有相关数据和方法保存在一个组件中,并在不同的控制器中重复使用。

那么为什么不使用角度服务或工厂,因为它们都是单身,是的,我们可以同时使用两者,想法是构建组件,并重新使用它而不仅仅是使用控制器