我正在寻找一种从服务器动态加载我的应用程序内容的解决方案。
我的场景:
假设我们有 2 个用户(A 和 B),我的应用程序由不同的模块组成,比如可以说一个 shoppingList 和一个计算器,现在我的目标是用户从数据库登录到我的应用程序我获得用户权限以及取决于什么权限他有,我会从服务器加载视图的 html 和逻辑部分的控制器文件,同时我会创建 html 和 ctrl 所需的状态。所以基本上我的应用程序与登录非常一致,其他所有内容都根据用户权限从服务器中提取。
我用什么:
- 科尔多瓦
- AngularJs
- 离子框架
为什么我需要它是动态的:
1)拥有一个仅包含登录逻辑的应用程序的可能性,因此在修复错误或添加模块时,我只需将文件添加到服务器,为用户提供权限,并且无需更新应用程序即可。
2)用户只有他需要的功能,当他只有1个模块的权利时,他不需要拥有一切。
3)App现在变得非常大,这意味着每个模块都有5-10个状态,有自己的html和控制器。目前计划了 50 个不同的模块,因此您可以进行数学计算。
我看了这个以获得一些灵感:
到目前为止我尝试了什么:
我创建了 1 个包含整个模块的 Html 文件,所以我只有 1 个 http 请求:
可以说这是我在用户登录后服务器的响应
HTML部分:
var rights= [A,B,C,D]
angular.forEach(rights, function (value, key) {
$http.get('http://myServer.com/templates/' + value + '.html').then(function (response) {
//HTML file for the whole module
splits = response.data.split('#');
//Array off HTMl strings
for (var l = 1; l <= splits.length; l++) {
//Putting all Html strings into templateCache
$templateCache.put('templates/' + value +'.html', splits[l - 1]);
}
}
});
控制器部分:
var rights= [A,B,C,D]
angular.forEach(rights, function (value, key) {
$http.get('http://myServer.com/controller/' + value + '.js').then(function (response) {
// 1 file for the whole module with all controllers
splits = response.data.split('#');
//Array off controller strings
for (var l = 1; l <= splits.length; l++) {
//Putting all Controller strings into templateCache
$templateCache.put('controllers/' + value +'.js', splits[l - 1]);
}
}
});
加载控制器后,我尝试注册它们:
$controllerProvider.register('SomeName', $templateCache.get('controllers/someController));
这是行不通的,因为这只是一个字符串......
定义提供者:
.config(function ($stateProvider, $urlRouterProvider, $ionicConfigProvider, $controllerProvider) {
// turns of the page transition globally
$ionicConfigProvider.views.transition('none');
$stateProviderRef = $stateProvider;
$urlRouterProviderRef = $urlRouterProvider;
$controllerProviderRef = $controllerProvider;
$stateProvider
//the login state is static for every user
.state('login', {
url: "/login",
templateUrl: "templates/login.html",
controller: "LoginCtrl"
});
//all the other states are missing and should be created depending on rights
$urlRouterProvider.otherwise('/login');
});
UI路由器部分:
//Lets assume here the Rights Array contains more information like name, url...
angular.forEach(rights, function (value, key) {
//Checks if the state was already added
var getExistingState = $state.get(value.name)
if (getExistingState !== null) {
return;
}
var state = {
'lang': value.lang,
'params': value.param,
'url': value.url,
'templateProvider': function ($timeout, $templateCache, Ls) {
return $timeout(function () {
return $templateCache.get("templates" + value.url + ".html")
}, 100);
},
'ControllerProvider': function ($timeout, $templateCache, Ls) {
return $timeout(function () {
return $templateCache.get("controllers" + value.url + ".js")
}, 100);
}
$stateProviderRef.state(value.name, state);
});
$urlRouter.sync();
$urlRouter.listen();
目前情况:
我已经设法加载 html 文件并将它们存储在 templateCache 中,甚至加载它们,但前提是状态是预定义的。我在这里注意到的是,有时可以说当我从列表中删除一个项目并返回查看项目又在那里了,也许这与缓存有关我不太确定......
我已经设法加载控制器文件并将控制器保存在模板缓存中,但我真的不知道如何将 $ControllerPrioviderRef.register 与我存储的字符串一起使用......
创建状态确实有效,但控制器不适合,所以我无法打开任何视图......
PS:我还查看了 require.js 和 OCLazyLoad 以及这个示例动态控制器示例
更新:
好的,所以我设法加载,Html
创建一切似乎工作正常,除了控制器似乎根本不工作,没有错误,但似乎没有执行控制器逻辑。目前,从先前下载的文件中注册控制器的唯一解决方案是使用这更像是一种破解而不是正确的解决方案。State
Controller
eval(),
这里的代码:
.factory('ModularService', ['$http', ....., function ( $http, ...., ) {
return {
LoadModularContent: function () {
//var $state = $rootScope.$state;
var json = [
{
module: 'Calc',
name: 'ca10',
lang: [],
params: 9,
url: '/ca10',
templateUrl: "templates/ca/ca10.html",
controller: ["Ca10"]
},
{
module: 'SL',
name: 'sl10',
lang: [],
params: 9,
url: '/sl10',
templateUrl: "templates/sl/sl10.html",
controller: ['Sl10', 'Sl20', 'Sl25', 'Sl30', 'Sl40', 'Sl50', 'Sl60', 'Sl70']
}
];
//Load the html
angular.forEach(json, function (value, key) {
$http.get('http://myserver.com/' + value.module + '.html')
.then(function (response) {
var splits = response.data.split('#');
for (var l = 1; l <= value.controller.length; l++) {
$templateCache.put('templates/' + value.controller[l - 1] + '.html', splits[l - 1]);
if (l == value.controller.length) {
$http.get('http://myserver.com//'+value.module+'.js')
.then(function (response2) {
var ctrls = response2.data.split('##');
var fullctrl;
for (var m = 1; m <= value.controller.length; m++){
var ctrlName = value.controller[m - 1] + 'Ctrl';
$controllerProviderRef
.register(ctrlName, ['$scope',...., function ($scope, ...,) {
eval(ctrls[m - 1]);
}])
if (m == value.controller.length) {
for (var o = 1; o <= value.controller.length; o++) {
var html = $templateCache
.get("templates/" + value.controller[o - 1] + ".html");
var getExistingState = $state.get(value.controller[o - 1].toLowerCase());
if (getExistingState !== null) {
return;
}
var state = {
'lang': value.lang,
'params': value.param,
'url': '/' + value.controller[o - 1].toLowerCase(),
'template': html,
'controller': value.controller[o - 1] + 'Ctrl'
};
$stateProviderRef.state(value.controller[o - 1].toLowerCase(), state);
}
}
}
});
}
}
});
});
// Configures $urlRouter's listener *after* your custom listener
$urlRouter.sync();
$urlRouter.listen();
}
}
}])
任何帮助表示赞赏