我正在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',所以我可以在整个应用程序中使用此函数。但是这个控制器正在通过很多功能/过程来复杂维护。
答案 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访问所有项目
将所有相关数据和方法保存在一个组件中,并在不同的控制器中重复使用。
那么为什么不使用角度服务或工厂,因为它们都是单身,是的,我们可以同时使用两者,想法是构建组件,并重新使用它而不仅仅是使用控制器