Я ищу решение для динамического загрузки содержимого приложения с сервера.
Мой сценарий:
Предположим, что у нас есть 2 пользователя (A и B), мое приложение состоит из разных модулей, например, скажем, shoppingList и калькулятор, теперь моя цель будет заключаться в том, что пользователь регистрируется в моем приложении из базы данных, я получаю права пользователя и в зависимости от того, какие права у него есть, я бы загрузил html для представлений и файлов контроллера для логической части с сервера, делая это, я бы создал состояния, необходимые для html и ctrl. Таким образом, в основном мое приложение очень мало соответствует логину, и все остальное вытаскивается с сервера в зависимости от Userrights.
Что я использую:
- Кордова
- AngularJs
- Ionic Framework
Зачем мне это нужно, чтобы быть динамичным:
1) Возможность иметь приложение, содержащее логику входа в систему, поэтому при исправлении ошибок или добавлении модулей мне нужно только добавить файлы на сервер, чтобы предоставить Пользователю право на это, и он там, не нуждаясь в обновлении приложение.
2) Пользователь имеет только те функции, которые ему нужны, ему не нужно иметь все, только когда он имеет право на 1 модуль.
3) Приложение становится очень большим в данный момент, то есть каждый модуль имеет 5-10 состояний с собственными html и контроллерами. в настоящее время запланировано 50 различных модулей, поэтому вы можете выполнить математику.
Я посмотрел на это, чтобы получить вдохновение:
AngularJS, ocLazyLoad и загрузка динамических состояний
То, что я пробовал до сих пор:
Я создал 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-Router:
//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, даже загрузить их, но только если состояния были предопределены. Что я заметил здесь, это то, что иногда позволяет сказать, когда я удаляю элемент из списка и возвращаюсь к View the item was there again, возможно, это имеет какое-то отношение к кешу, я не уверен...
Мне удалось загрузить файлы контроллера и сохранить контроллеры в templateCache, но я действительно не знаю, как использовать $ControllerPrioviderRef.register с моими сохраненными строками...
Создание состояний действительно работало, но контроллер не входил, поэтому я не мог открыть никаких просмотров...
PS: Я также посмотрел на require.js и OCLazyLoad, а также на этот пример пример динамического контроллера
Update:
Итак, мне удалось загрузить 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 listener *after* your custom listener
$urlRouter.sync();
$urlRouter.listen();
}
}
}])
Любая помощь оценена