Q1) I need help with overriding System package in mean.io? I am trying to create my own home page.
So I did this
angular.module('mean.mysystem', ['mean.system'])
.config(['$viewPathProvider',
function($viewPathProvider) {
$viewPathProvider.override('system/views/index.html', 'mysystem/views/index.html');
}
]);
I get following error http://errors.angularjs.org/1.3.2/ng/areq?p0=MysystemController&p1=not+aNaNunction%2C+got+undefined
Can anyone suggest a resolution or a better way to do this?
Q2) Also, is this the right way to extend a package
Mysystem.register(function(app, auth, database, System) {
Does mean know the package to extend from a variable name?
Don't know why, but removing the ['mean.system'] worked for me. Something as below,
angular.module('mean.mysystem')
.config(['$viewPathProvider',
function($viewPathProvider) {
$viewPathProvider.override('system/views/index.html', 'mysystem/views/index.html');
}
]);
This might be the why: "angular.module('mean.mysystem', ['mean.system'])" creates a new module which probably is in conflict with the one MEAN creates during package registration.
Creation versus Retrieval
Beware that using angular.module('myModule', []) will create the module myModule and overwrite any existing module named myModule. Use angular.module('myModule') to retrieve an existing module.
See detail # https://docs.angularjs.org/guide/module
Angular Modules and Dependencies
Every package registration automatically creates a corresponding angular module of the form mean.[package-name]
See detail # https://github.com/linnovate/mean#angular-modules-and-dependencies
You can just add:
$stateProvider
.state('/', {
url: '/',
templateUrl: 'youPackage/views/index.html'
});
into your routes file.
$viewPathProvider not exist in older version of mean.io, for example in this used by openshift quickstart.
Related
I'm using gulp to combine my scripts in order to load only one file in HTML (make it faster).
Here's a sample code, name of libraries don't matter much, you'll get the idea :
// gulpfile.js
mix.scripts([
'vendor/jquery-2.1.1.min.js',
'vendor/angular.js',
'vendor/slideout.min.js',
'vendor/dirPaginate.js',
'vendor/cookie.js'
], 'public/js/libs.js');
And then I do this :
// app.js
let app = angular.module('app', ['angular-slideout', 'cookie', 'dir-paginate'], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
export default app;
I only use one file to load every NG library in my project, and then I import this app in my controllers. Now this is only an example, but I already have conflicts depending on the order of mixing these scripts in.
Any advice on processing this ? I already had to ditch some libs I wanted to use because they were conflicting with others. Going on this way, this looks like a dead end.
I understand that requirejs and browserify can load my files dependent on its current context, and that it is amazing. I would really prefer to use the #section sections syntax that the razor engine uses. Was just wondering if there is a way to implement this into a typescript / angularjs application.
for example
index.html
#renderSection scripts;
// which could turn into something like
<script data-render="scripts"></scripts>
// the app.run() could declare all the scripts that will be needed on every
// page view
view.html
<script ng-section-repeat="injected in injection"></script>
// the ng-section-repeat is basically taking all the items in the
// typescript constructor and then finding out which ones are needed for
// that view.
I like the idea injecting application file dependencies in the view , without a configuration file and all the added extras that comes with the loaders.
I just want to easily define what files are needed in the actual view and get them loaded, with angular's dependency injection handling the dependency itself.
If you are handling all your dependencies with $inject then , as far as i can tell, dependency is technically already setup in the controllers, all one would need, is to load this as it is called. Which could even eliminate the need for the #section scripts completely
Update:
What i have done to sort of replicate the module loaders is to just use gulp-concat and define the file order in my gulp.config.js and then pass it to the gulp-src before running $.concat .this allows me to have the files in the gulp steam , in dependent order . They are however loaded on the first load. With gulp-uglify the files are tiny ( its now at 566Kb with 16 external libraries loading in 69ms . To put that into perspective it takes 209ms to load one google font ).
I dont know maybe i am not understanding browserify correctly but i honestly struggle to see the need for it, its seems extremely convoluted for something so simple
It is possible using external modules and an injector to do what you asked for:
I just want to easily define what files are needed in the actual view
import {UserFactory} from 'models/userFactory';
import {UserValidator} from 'models/userValidator';
import {Inject} from 'angular2/di';
and get them loaded, with angular's dependency injection handling the dependency itself.
Note: My example uses angular 2.x because I less familiar with angular 1.x and I'm sure you can do something really similar...
class SomeComponent {
userName: string;
userRating: number;
rating: number;
constructor(
#Inject(UserFactory) UserFactory
#Inject(UserValidator) UserValidator
)
{
this.UserFactory = UserFactory;
this.UserValidator = UserValidator;
}
}
Then you can use Browserify to create a bundle.js file that can be executed in a web browser.
I am trying to have external modules change my $translateProvider.translation on the main module. see this as a "tranlation plugin" for my app.
it seems like changing translations from the $translate service is not possible.
mymodule.service('MyService', function ($translateProvider) {
var lib = function () {
//EDITED FOR BREVITY
this._registerTranslations = function (ctrl) {
if (!ctrl.i18n) return;
for (var name in ctrl.i18n) {
/////////////////////////////
// THIS IS THE PLACE, OBVIOUSLY PROVIDER IS NOT AVAILABLE!!!!
$translateProvider.translations(name, ctrl.i18n[name]);
//////////////////////////////
}
};
//EDITED FOR BREVITY
};
return new lib();
});
anyone with a bright idea?
So, to answer your question: there's no way to extend existing translations during runtime with $translate service without using asynchronous loading. I wonder why you want to do that anyway, because adding translations in such a way means that they are already there (otherwise you would obviously use asynchronous loading).
Have a look at the Asynchronous loading page. You can create a factory that will load a translation from wherever you want.
I created an Angular constant to hold new translations. If I want to add a new translation, I add it to the constant. Then in my custom loader, I first check the constant to see if the translation exists (either a new one, or an updated one). If so, I load it from the constant. If not, I load it from a .json file (or wherever you load your initial translations from). Use $translate.refresh() to force translations to be reloaded and reevaluated.
Demo here
The demo is pretty simple. You would need to do a little more work if you wanted to just change a subset of the translations, but you get the general idea.
From the AngularJS docs (https://docs.angularjs.org/guide/providers):
You should use the Provider recipe only when you want to expose an API for application-wide configuration that must be made before the application starts. This is usually interesting only for reusable services whose behavior might need to vary slightly between applications.
Providers are to be used with the application's .config function. $translateProvider for configuration, $translate for other services and controllers.
If I wanted to add my own custom "provider" to the list (in AngularPublic.js), like so:
...
$provide.provider({
$anchorScroll: $AnchorScrollProvider,
$animate: $AnimateProvider,
$browser: $BrowserProvider,
$cacheFactory: $CacheFactoryProvider,
$controller: $ControllerProvider,
$myCustomController: $MyCustomControllerProvider, <---- I made this
$document: $DocumentProvider,
$exceptionHandler: $ExceptionHandlerProvider,
$filter: $FilterProvider,
$interpolate: $InterpolateProvider,
...etc
If I used an existing provider as boilerplate, would this be a bad idea?
Yes, it is definitely a bad idea. I don't think it is reasonable to modify the source code of Angular as Angular itself is fast growing, things change every second, you may find it is hard to merge your change with newest Angular version one day.
If you only want to add your custom provider into ngModule, you can just to this.
var ngModule = angular.module('ng');
ngModule.provider('myCustom', function() {
// Your code goes here
});
Hope it may help you.
So I am exploring different configuration options for my app. My main goal is to find a way to configure the states/routes on the highest level even if dependent angular modules have their own routes/states declared. There are several options I have come up with but I'm not sure if they are possible or not:
Assume I have module1 which is dependent on module2
1: If module2 declares its own states/routes, is there a way I can delete or override them from module1?
2: Is there a way I can get a list of recommended states (objects that represent states such as {name: 'state', templateURL: '/someURL'} and use module1 to logically determine which stateObjects to give the $stateProvider?
3: Is it possible to access the stateProvider NOT in the config? For example, say I have the following that gets setup in the config:
tinkModule.config(function($stateProvider, $urlRouterProvider){
$stateProvider.state('create', {
url: '/create',
templateUrl: 'templates/create.html'
});
$stateProvider.state("otherwise", {
url: "/otherwise",
templateUrl: 'templates/tinkOtherwise.html'
});
$urlRouterProvider.otherwise('/otherwise');
});
Can I add a 'review' state after they have been through the create state?
Please let me know if there are other options that I am not thinking about and also let me know if any of the above is possible.
Sounds like your main goal is to define states across modules and also lazy load states. There is some existing features to accomplish these.
Register states across various modules:
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-ui-router-from-multiple-modules
You'll need to build 0.3.0 manually with grunt though: https://github.com/angular-ui/ui-router#developing
Then if you want to lazy load (define states on-the-fly) you can read about the $stateNotFound event: https://github.com/angular-ui/ui-router/wiki#state-change-events
And look at the ui-router test for lazy loading: https://github.com/angular-ui/ui-router/blob/master/test/stateSpec.js#L196-L208
The test shows how you might try to go to an undefined state, get the $stateNotFound error, which allows you to define the missing state at that time. It will always try once more to find the state, assuming that you may have defined it in the error callback.