I just create the project AngularJs 1.7 and webpack 4 with ES6 class on component and module setup.
this is my app main module.
// Core Styles
import './styles/main.scss';
// Core Angular
import angular from 'angular';
import { AppComponent } from "./app.component";
import CommonModule from './modules/common/common.module';
import PackagesModule from './modules/packages/packages.module';
import PackagesService from "./services/packages.service";
// These all export the module name
// import ngAnimateModuleName from 'angular-animate';
const dependencies = [
// ngAnimateModuleName
CommonModule.name,
PackagesModule.name
];
angular.module('app', dependencies)
.component('appComponent', AppComponent)
.service('PackagesService', ['$http', PackagesService]);
this is my js component file.
import './app.component.scss';
export const AppComponent = {
template: require('./app.component.html'),
controller: [
'PackagesService',
class AppController {
constructor (PackagesService) {
this.test = 11;
}
}]
};
But seems like test variable is not available inside the template file.
<header-component></header-component>
<div class="container">
<div class="row">
<div class="col-6">
<div class="packages-name-box">
<h1 class="homepage-title">Packages Name {{ test }}</h1>
<packages-list-group pages-data="pagesPackageData"></packages-list-group>
</div>
</div>
</div>
</div>
And this is HTML LOADER inside webpack.confing
{
// HTML LOADER
// Reference: https://github.com/webpack/raw-loader
// Allow loading html through js
test: /\.html$/,
loader: 'raw-loader'
}
Am i missing something why this.test is not display anything inside the template?
Thanks for your help!
Since you are not using ControllerAs syntax, you should assign the value to the $scope variable,
$scope.test = 11;
you need to inject $scope as
'PackagesService','$scope',
class AppController {
constructor (PackagesService,$scope) {
$scope.test = 11;
}
On angularjs components, all variables declared with this can be acessed by the object $ctrl on the scope. You should use:
<h1 class="homepage-title">Packages Name {{ $ctrl.test }}</h1>
you can change the object name to whatever you want on controllerAs like this: (but it's $ctrl by default)
export const AppComponent = {
template: require('./app.component.html'),
controllerAs: 'vm',
controller: [
'PackagesService',
class AppController {
constructor (PackagesService) {
this.test = 11;
}
}]
};
see angularjs component document: https://docs.angularjs.org/guide/component
Related
Here a very simple component
const MyComponent = Vue.component('my-component', {
data () {
// data here...
},
methods: {
// methods here...
},
template: '<p>Hello, world !!!</p>'
});
Is it a way to use a external file to write html code <p>Hello, world!</p> instead of the string template ?
I know it is a way with single file components (https://v3.vuejs.org/guide/single-file-component.html).
But unfortunately, i can't follow this way because in my context, i can't use tools like Vue CLI for example
The value of template in your example can be sourced from anywhere. So its possible to do:
template.js:
export default {
return "<p>Hello, world!!!</p>"
}
component.js
import template from 'template'
const MyComponent = Vue.component('my-component', {
template: template,
});
I have an angular2 app that displays chart data from a rest api.
I created the drawing code in my bulletchart.component file.
Now I want to outsource the code into a service.
But it seems like there is only one active instance of the data service.
This is my page content where I want to load the charts.
<div class="col">
<app-bulletchart [ID]="1" [apiAddress]="'http://url1'"></app-bulletchart>
</div>
<div class="col">
<app-bulletchart [ID]="2" [apiAddress]="'http://url2'"></app-bulletchart>
</div>
The template for the app.bulletchart is this:
<div class="panel test{{ID}}">
</div>
In my bulletchart.service file I change the DOM of the app-bulletchart with some methods like this:
initSvg() {
const identifier = '.test' + this.ID;
console.log("ident " + identifier);
this.svg = d3.select(identifier).append('svg')
.attr('class', 'bullet')
There are also methods that update the chart
drawRange() {
console.log("range " + this.ID);
// Update the range rects.
const range = this.g.selectAll('rect.range')
.data(this.ranges);
range.enter().append('rect')
I set the ID property of the bulletchart.service in the ngOnInit in bulletchart.component
But when I now try to use this.bulletchart.drawRange(); this method is only called for ID 1 and not for ID 2.
I don't understand why, because I thought it would do something like this:
create App-Bulletchart (ID=1) -> create instance of bulletchart.service (with ID = 1)
create App-Bulletchart (ID=2) -> create instance of bulletchart.service (with ID = 2)
Edit:
I added providers: [BulletchartService] to my bulletchart.component file and removed it from the app.module and now it works.
But why?!
you may include service provider in the component to ensure service is created for each instance of component
#Component({
...
providers:[BulletchartService]
...
})
Example
#Injectable()
export class AppService{
Id: string;
someMethod(){
console.log(this.Id);
}
}
#Component({
selector: 'my-child',
template: `<h1>Child ID {{Id}}</h1>
<button (click)="invokeService()" >Invoke service</button>
`,
providers:[AppService]
})
export class ChildComponent {
#Input() Id: string;
constructor(private svc: AppService){}
ngOnInit(){
this.svc.Id = this.Id;
}
invokeService(){
this.svc.someMethod();
}
}
#Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1>
<my-child [Id]="1" ></my-child>
<my-child [Id]="2" ></my-child>
`
})
export class AppComponent {
name = 'Angular';
}
#NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent, ChildComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Check this Plunker.
Hope this Helps!!
using this repo for angular boilerplate
https://github.com/AngularClass/NG6-starter
But I found hard to access the dom inside angular component's $postLink phase.
Am I coding it wrong? Or do I have to use directive which is not optimal for one way binding?
about.component.js
import template from './about.html';
import controller from './about.controller';
import './about.scss';
let aboutComponent = {
restrict: 'E',
bindings: {},
template,
controller,
};
export default aboutComponent;
about.controller.js
class AboutController {
constructor() {
this.name = 'about';
this.$postLink = ($element) => {
console.log($element); // here is when I want to utilize the element!
}
}
}
export default AboutController;
about.js
import angular from 'angular';
import uiRouter from 'angular-ui-router';
import aboutComponent from './about.component';
let aboutModule = angular.module('about', [
uiRouter
])
.config(($stateProvider) => {
"ngInject";
$stateProvider
.state('about', {
url: '/about',
component: 'about'
});
})
.component('about', aboutComponent)
.name;
export default aboutModule;
about.html
<section>
<navbar></navbar>
<h1>{{ $ctrl.name }}</h1>
<section>
About us.
</section>
</section>
You can't get $element(directive element) from $postLink lifecycle hook. You have to inject $element inside controller constructor to get directive element inside directive.
class AboutController {
static $inject = ["$element"]
constructor($element) {
this.name = 'about';
this.$element = $element;
}
// better move out $postLink outside controller.
$postLink = () => {
console.log($element);
}
}
export default AboutController;
I have angular 2 application written on javascript. I want to migrate it to typescript.
JS code is:
(function (app) {
app.SomeService = ng.core
.Class({
constructor: [app.AnotherService, function SomeService(s) {
this._anotherService = s;
}],
someFunction: function(){
...
}
.....
});
})
(window.app || (window.app = {}));
I want to inject this service into my typescript component. How can I do that?
I tried to use it like this:
#Component({...})
export class SomeComponent {
constructor(public someService: window.app.SomeService) {
}
}
But it does not work.
The way I've managed to mix JS and TS is to have a file with the JS, in your case let's say it's src/app.js , with the code you posted above.
At this point you can do one of two things:
You create a component that is going to use said JS code, something like:
import {Component} from "angular2/core";
#Component({
selector: 'app',
template: ` <a> <onclick='app()'>When the function is clicked, use app() code</a>
,
directives: []
})
export class App {
constructor(){
}
}
The template is going to depend on what your code is supposed to do. I often use onClick, but here you have an example of what it might look like:
template: `<input value="Select Date" type="text" class="datepicker" onclick ="myCalendar()" >
`
Another option is to call the JS code from the constructor
import {Component} from 'angular2/core';
#Component({
selector: 'app',
template: `
<div>
</div>
`,
directives: []
})
export class MyApp {
name:string;
constructor() {
this.name='Angular 2';
app();
}
}
So it depends on what you want to do, and when, as far as I can tell. There are people with more experience but I tried to not say anything wrong, and provide code similar to what I have working right now.
I'm following the angular tutorial on the basics of Angular2, trying to translate it to javascript since it is currently only available for Typescript.
I currently have two files: app.component.js and hero-detail.component.js.
Located in app.component.js i have my AppComponent. From this, I would like to load the component in hero-detail.component.js as a directive.
My current code looks like this, but I can't figure out how to load HeroDetailComponent:
app.AppComponent =
ng.core.Component({
selector: 'my-app',
inputs : ['hero'],
directives: [HeroDetailComponent],
template: `<h1>{{title}}</h1>My Heroes<h2></h2>
<ul class="heroes">
<li *ngFor="let hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
`
})
.Class({
constructor: function() {
this.title = 'Tour of Heroes'
this.heroes = HEROES
this.selectedHero = null
},
onSelect(hero) { this.selectedHero = hero; }
});
})(window.app || (window.app = {}));enter code here
In Javascript, all variables are bound to the app which is in turn bound to the window.
You should define your HeroDetailComponent the same way AppComponent is defined.
(function (app) {
app.HeroDetailComponent = ng.core.Component({
selector: 'hero-detail',
inputs: ['hero'], // <-- this is necessary to receive the "selectedHero"
template: ` <!-- ... --> `
}).Class({
constructor: function () {
}
});
})(window.app || (window.app = {}));
Make sure to include the file in your index.html
<!-- 2. Load our 'modules' -->
<script src='app/hero.js'></script>
<script src='app/hero-detail.component.js'></script>
<script src='app/app.component.js'></script>
<script src='app/main.js'></script>
In your AppComponent, add the newly created HeroDetailComponent like so
app.AppComponent = ng.core.Component({
directives: [app.HeroDetailComponent], <-- // note the dependence on the `app` object
// ... and other things
}).Class({ /* Class Declaration */ });