Open atrusch opened 9 years ago
Hmm this is probably a race condition, and the controller gets called before the ocLazyLoad directive is able to remove the dom. This directive needs a rewrite because there are a few bugs that are hard to fix right now.
Could you try something like this ?
$ocLazyLoadProvider.config({
modules: [{
name: 'searchUserWithSkill', // give the name that you want here
files:[
'webjars/ng-grid/2.0.14/ng-grid.min.js',
'plugins/usl_userSkills/searchUserWithSkill/services/usl_searchService.js',
'plugins/usl_userSkills/searchUserWithSkill/controllers/usl_searchUserCtrl.js'
]
}]
});
{
url : '/skills_user_search',
views : {
'RootView' : {
templateUrl : 'plugins/usl_userSkills/searchUserWithSkill/usl_searchUserWithSkill.html'
}
},
resolve : {
modules : ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
serie : true,
files :[
{type: 'css', path:'webjars/angular-ui-select/0.11.2/select.min.css'},
{type: 'css', path:'js/thirdparty/angular/tree-grid-directive/treeGrid.css'},
{type: 'css', path:'webjars/ng-grid/2.0.14/ng-grid.min.css'},
'webjars/angular-ui-select/0.11.2/select.min.js',
'js/thirdparty/angular/tree-grid-directive/tree-grid-directive.js',
'plugins/usl_userSkills/usl_treeSkills.js',
'plugins/usl_userSkills/searchUserWithSkill/usl_searchUserWithSkill.js'
]
});
}]
}
}
<section class="content-header">
<h1>
{{'Search Users with skills' | translate}}
</h1>
</section>
<!-- searchUserWithSkill is the same name as in config, it's a string so double quote followed by single quote -->
<section class="content" oc-lazy-load="'searchUserWithSkill'">
<div class="box box-default" ng-controller="usl_searchUserCtrl">
<div class="box-header with-border">
<h3 class="box-title ng-binding">{{'Selected skills' | translate}}</h3>
</div>
<div class="box-body">
<form name="formuser" novalidate class="form-horizontal">
<div class="col-xs-12" ng-if="skillList.length > 0">
<ui-select multiple ng-model="selected.skills" theme="select2" style="width:100%">
<ui-select-match placeholder="Select a skill...">{{$item.text}}</ui-select-match>
<ui-select-choices repeat="skill in skillList | propsFilter: {text: $select.search}">
{{skill.text}}
</ui-select-choices>
</ui-select>
</div>
<div class="pull-right">
<br/>
<button class="btn btn-primary" ng-disabled="selected.skills.length == 0" ng-click="searchUsers()">{{'Search' | translate}}</button>
</div>
</form>
</div>
</div>
<div class="box box-default">
<div class="box-body">
<div class="gridStyle" ng-grid="gridOptions" ng-if="gridData.length > 0"></div>
</div>
</div>
</section>
Thanks for you fast response.
Actually I load elements only on demand. But what I really don't understand it is why if I try to load my controller in the resolve like this :
{
url : '/skills_user_search',
views : {
'RootView' : {
templateUrl : 'plugins/usl_userSkills/searchUserWithSkill/usl_searchUserWithSkill.html',
controller : function($scope,modules) {
alert(modules);
$scope.ocLazyLoad = {
files:[
'webjars/ng-grid/2.0.14/ng-grid.js',
'plugins/usl_userSkills/searchUserWithSkill/services/usl_searchService.js',
]
}
}
}
},
resolve : {
modules : ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
serie : true,
files :[
{type: 'css', path:'webjars/angular-ui-select/0.11.2/select.min.css'},
{type: 'css', path:'js/thirdparty/angular/tree-grid-directive/treeGrid.css'},
{type: 'css', path:'webjars/ng-grid/2.0.14/ng-grid.min.css'},
'webjars/angular-ui-select/0.11.2/select.min.js',
'js/thirdparty/angular/tree-grid-directive/tree-grid-directive.js',
'plugins/usl_userSkills/usl_treeSkills.js',
'plugins/usl_userSkills/searchUserWithSkill/usl_searchUserWithSkill.js',
'plugins/usl_userSkills/searchUserWithSkill/controllers/usl_searchUserCtrl.js'
]
});
}]
}
}
I have the following error :
Error: [ng:areq] http://errors.angularjs.org/1.4.1/ng/areq?p0=usl_searchUserCtrl&p1=not%20aNaNunction%2C%20got%20undefined
at Error (native)
Normally the controller is loaded 1rst and template only after no ?
Actually I think that the router is loading the template and then the controller (because the controller will be applied to your template).
But the resolve is loaded before the controller & the template.
So why it say that the function does not exist ? The function is defined in plugins/usl_userSkills/searchUserWithSkill/controllers/usl_searchUserCtrl.js
Code
"use strict";
angular.module('usl_searchUserWithSkill').controller('usl_searchUserCtrl',
function($scope, $digLog, Restangular, usl_treeSkillsService, usl_searchService){
$scope.selected = { skills : [] };
$scope.skillList = [];
And when I load it with the ocLazyLoader directive it can found it. Can you explain me this behaviour.
Not really :-/
Hi,
As you suggest it really seems a race problem. I have notice that if I put a breakpoint on
broadcast(newModule ? "ocLazyLoad.moduleLoaded" : "ocLazyLoad.moduleReloaded", moduleName);
if (angular.isDefined(runBlocks[moduleName]) && (newModule || params.rerun)) {
tempRunBlocks = tempRunBlocks.concat(runBlocks[moduleName]);
}
_invokeQueue(providers, moduleFn._invokeQueue, moduleName, params.reconfig);
_invokeQueue(providers, moduleFn._configBlocks, moduleName, params.reconfig); // angular 1.3+
broadcast(newModule ? "ocLazyLoad.moduleLoaded" : "ocLazyLoad.moduleReloaded", moduleName);
registerModules.pop();
justLoaded.push(moduleName);
And an alert in the controller state definition
{
url : '/skills_user_search',
views : {
'RootView' : {
templateUrl : 'plugins/usl_userSkills/searchUserWithSkill/usl_searchUserWithSkill.html',
controller : function($scope,modules) {
alert(modules);
$scope.ocLazyLoad = {
files:[
'webjars/ng-grid/2.0.14/ng-grid.js',
'plugins/usl_userSkills/searchUserWithSkill/services/usl_searchService.js',
]
}
}
}
},
resolve : {
modules : ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
serie : true,
files :[
{type: 'css', path:'webjars/angular-ui-select/0.11.2/select.min.css'},
{type: 'css', path:'js/thirdparty/angular/tree-grid-directive/treeGrid.css'},
{type: 'css', path:'webjars/ng-grid/2.0.14/ng-grid.min.css'},
'webjars/angular-ui-select/0.11.2/select.min.js',
'js/thirdparty/angular/tree-grid-directive/tree-grid-directive.js',
'plugins/usl_userSkills/usl_treeSkills.js',
'plugins/usl_userSkills/searchUserWithSkill/usl_searchUserWithSkill.js',
'plugins/usl_userSkills/searchUserWithSkill/controllers/usl_searchUserCtrl.js'
]
});
}]
}
}
That the controller is found. Is it possible to put a delay between the modules loading et the final resolve ?
An other thing is the order the modules are loaded
Why ngGrid elements are reload and not the main module.
No it's not possible, and it should work without it. Why do you load some files in the "controller" of your view, and not all of them in the resolve ?
Because if I do this he can't find all my controllers, filters, .... when he display the page. I can show you directly with a teamviewer if you want.
I can't (I don't have teamviewer & I'm at work), but if you could set up a plunkr or a zip (at olivier.combe@gmail.com) that would be much easier to debug
Thanks again for your fast response The plunkr link http://plnkr.co/edit/c6FoQj3HZASXuCEiDtRZ
Ok here is the problem: in the file "myprofilectrl.js", you inject the service "usl_treeSkillsService", but this service is never defined. Remove this injection from the controller and it works: http://plnkr.co/edit/slFOec6HFstHP8MfvsZB?p=preview
Hi,
If you look pluginmanager I load in the ui-route state the module
modparent.js
var plugins = {"plugins" : [{"name":"myprofile_details","navigation":{"id":"1","title":"My Profile","glyphicon":"fa-user","order":10,"homepriority":10,"children":[{"id":"myprofile_details","title":"Details","glyphicon":"fa-circle-o","url":"myprofile_details","order":10,"homepriority":10,"parent":"1"}]},"state":{
url : '/myprofile_details',
views : {
'RootView' : {
templateUrl : 'myprofile.html',
}
},
resolve : {
modules : ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
serie : true,
files :[
'modparent.js',
'myprofile.js',
'myprofilectrl.js'
]});
}]
}
}}
]};
The code of this one is :
"use strict";
angular.module('usl_treeSkills',["oc.lazyLoad","my_profile"]);
angular.module('usl_treeSkills').run(function($ocLazyLoad){
$ocLazyLoad.load({
files : [
'modparentService.js'
]
})
});
The module is loaded before the other. So it must know this service, no ?
if you need a service from another module, then you need to reference this module as a dependency for your module. And "modparentService.js" is loaded at "run", so it is not available when you call load the first time.
Hi,
Thanks for the analyze. For maintenance purpose I want to keep my module in multiple files. But also when dependencies exist to load only one file which describe the complete module.
Is it possible to do this kind of things ? If you are agree I will do it with a little help or advice.
Regards
It is possible, but I don't know if it will be easy :)
Ok, I'am looking your code. I understand how the elements are loaded, but what happens to promise after. What function is it called on success ? Maybe I could add a new loader (as jsLoader, cssLoader) when all the code is readed call buildelement for each js defined in the readed file. But after I don't understand how this files are registered into Angular. Too many promise. Can you give me a clue ?
Regards
The registering with angular happens in the _register
function (in ocLazyLoad.core.js
), and especially in the _invokeQueue
where I'm calling the provider that should register the component with angular.
Hi,
I am writing an application with ui-router state defined dynamically on startup. I used angular 1.4.1 and ocLazyLoad 1.0.1
When all goes well the scope tree is the following :
But sometimes the scope tree for the same page is :
There is a new scope 53 (duplicate of ng-controller) and ng-controller is a sibling. If you have a scope function it will call 2 times for one event. We can make an TeamViewer if needed.
state definition
Template