I know there are many ways to create both static and dynamic page titles with angular, but the best way I've found so far is angular-ui-router-title.
Briefly, it works like this:
$stateProvider.state('a', {
...
resolve: {
$title: function () { return 'a title'; }
}
...
}
and in the view:
<title ng-bind="$title"></title>
Now I'd like to get localisation working dynamically too, with angular-translate. When the user changes language in my application, an event is fired on the root scope and I use $translate.use() to change the language in use.
I figured I'd just be able to do this:
<title ng-bind-template="{{$title | translate}}"></title>
where the resolved title is now a translate key, and it would work, but it doesn't. Is there any other way I can get this translation to happen at runtime?
Related
I'm working in a project with vue-cli and they want me to generate a listlike view (pun intended) onto data from the database.
I've never really worked with vue. 4 months ago I was given some time to find my way into it, but then I had to work on our lumen-driven backend api and so I forgot most of the stuff. And besides that, I really find vue utterly confusing.
So I need to do this step by step since I dont have loads of time at hand to throughly learn the framework before actually producing usable results.
I have the following template:
<template>
<div>
<h1>myList</h1>
<table id="testTable"></table>
<button class="button" v-on:click='fetchList'>myButton</button>
</div>
</template>
<script>
import store from "../store/store";
import { USER_FETCHLIST } from "../store/actions/user";
export default {
data () {
return {
}
},
methods: {
fetchList: function(){
var test = store.dispatch(USER_FETCHLIST).then((res)=> {
console.log(res)
document.getElementById("testTable").InnerHTML = res
})
}
}
}
</script>
<style>
</style>
The fetchList() successfully fetches the data from the DB. But I cant insert anything into my table element, at least not this "javascript-way" which I tried in the above code.
For example, when I try to input this string: <tr><td>1</td><td>2</td></tr> into the table element, nothing happens.
I learnt about v-bind and all this stuff, but I really don't know how to implement it here.
I also must emphasize that I absolutely want to avoid building this component from subcomponents.
The "inheritance" in vue.js is pretty different from the usual inheritance in programming and I really tried to get my head around it, but I just cant make anything useful with it in my relatively short timeframe.
So I need to have all the JS and html in place in this component.
Can anyone give me a hand in propery binding the prefabricated HTML-String to the table element?
Thank you!
I am new to ember and I am building a DnD character sheet to learn and practice. Right now I am having a lot of trouble getting access to model data in a controller. After hours and hours of reading related posts it is just not clicking and I think I am misunderstanding what I am passing to the controller.
Basically what I am trying to do is grab data from a model so I can do calculations on them and then display the results of those calculations on the page.
Here is my transforms/router.js:
Router.map(function() {
this.route('characters', { path: '/'})
this.route('new', {path: 'new'});
this.route('view', {path: '/:character_id'});
});
So here I am trying to pull up the view page which has the URL of the character id. Next here is my route for the view page:
export default Route.extend({
character: function () {
return this.store.findRecord('character', id)
}
});
So this is finding the record of the character with the id I pass. My link looks like this and is coming from a component:
<h5 class="card-title">{{#link-to 'view' id}}{{name}}{{/link-to}}</h5>
Now I have my controller for the view page, which looks like this:
init(id){
let character = this.get('character')
}
When I try to log character, it is still undefined. When looking ember information in dev tools it seems the page is getting the information from the model after I refresh the page, but I just can't seem to be figure out how to grab that info in the controller itself to manipulate it.
I've been trying to figure this out for quite a while now, and its getting pretty frustrating. I currently have a work around where I do the calculations beforehand and just store all the calculated results in the model as well, but while I am learning I would like to understand how this works. Thanks is advance.
Edit: As pointed out in comments below I was missing let when defining character.
Your model hook seems wrong. You're using id but never define it. Probably what you want is more like this:
character(params) {
return this.store.findRecord('character', params.character_id);
}
Next your init hook makes no sense:
init(id){
let character = this.get('character')
}
First there is no id passed to the init hook. Second you're missing this._super(...arguments) which should always be called when you override init.
Last is that your controller is first created and later populated with the model. Also the model is populated as model property, not character.
So you could place this in your routes template and it will work:
This is character {{model.id}}
Or if you want to change something before you pass it to the template you should use a computed property in your controller:
foo: computed('model.id', function() {
return this.get('model.id') + ' is the id of the character';
}),
However for this code to run you need to use. The easiest way to use it is to put it into your template:
{{foo}}
I'm trying to implement communication between my view models in a knockoutjs driven application. I scaffolded it using yeoman tool, and as you can see it uses AMD:
define(['knockout', 'signals', 'text!./nav-bar.html'], function(ko, Signal, template) {
function NavBarViewModel(params) {
this.route = params.route;
}
return { viewModel: NavBarViewModel, template: template };
});
I have to define an object that I would later use to dispatch events, right? Something like that:
var EventDispatcher = {
itemClicked: new Signal()
};
And then, whenever something happens in the NavBarViewModel I'd like to do:
EventDispatcher.itemClicked.dispatch();
The problem is - where should I put this EventDispatcher thing? It's obvious that it should be some kind of a global object, so that every VM could get a hold on it, but it would be ugly. Dependency injection came to mind, since everything else in this architecture I choose is done this way, but how to achieve that? I come from WPF, MVVM world, and so far I've used MVVMLight framework which had this great Messenger component. Is there anything like that in the JS world (and if it's js-signals lib I'm already using, then how should I use it to achieve my goal?)
I could also use the subscribable object built into the knockout fw, but the question still stands - where to put it (or how to share the instance between VMs)?
You'd quite simply inject it by including it in your define.
First, create a new file, EventDispatcher.js with your EventDispatcher code inside (and other relevant Knockout bits, like returning the view model and whatnot).
Then in your current file add it in:
define([ ... , ... , "EventDispatcher"], function( ... , ... , EventDispatcher )
Now you can simply call its methods within this file by using:
EventDispatcher.itemClicked.dispatch()
(Where EventDispatcher is what we've named it in our define parameters).
Do bear in mind though that your EventDispatcher.js file will also need the signals file passed to it through its own define wrapper.
I'm trying to build multilingual website in AngularJS. Delivering proper translation in templates seems pretty straightforward but I'm stuck on implementing proper multilingual routes using UI-Router. I couldn't have found any suitable examples.
It has to scale easily while adding new languages. Example of routes structure for two languages is:
/en
/en/products
/en/products/green-category
/en/products/green-category/green-product-1
/cs
/cs/produkty
/cs/produkty/zelena-kategorie
/cs/produkty/zelena-kategorie/zeleny-produkt-1
Product categories are hard-coded, products are loaded from database.
I'm trying something like this (leaving out product categories since they are similar to 'products', just one level deeper in hierarchy):
$stateProvider.state('product', {
url: '/{lang:' + Translate.getLangs() + '}/{products:' + Translate.getRouteVariants('products') + '}/{productSlug}',
templateUrl: 'app/product.html',
resolve: {
product : function($stateParams){
return Data.products.get( Data.products.deslug($stateParams.productSlug, $stateParams.lang), $stateParams.lang );
}
}
});
And in controller / template:
$scope.productLink = function(id) {
return {
lang:$rootScope.lang,
products:Translate.getRoute('products', $rootScope.lang),
productSlug:Data.products.slug(1, $rootScope.lang)
};
}
<a ui-sref="product(productLink(1))">Green product 1</a>
Where
Translate, Data are providers
Translate.getLangs() -> 'en|cs'
Translate.getRoute('products', lang) -> 'products' or 'produkty' based on lang
Translate.getRouteVariants('products') -> 'products|produkty'
Data.products.slug(productId, lang) -> returns productSlug from model
Data.products.deslug(productSlug, lang) -> returns productId from model
Data.products.get(productId, lang) -> loads data
Handling with current language should be done better (probably in Translate provider).
Routes shouldn't match cross-lang urls such as '/en/produkty'. Big problem.
/edit: I probably could use $stateChangeStart, check whether all parametres are in one language and if not, redirect to top-level state.
And this whole solution doesn't seem way too elegant (since I'm begginer with Angular) so if anyone can provide any insights on this subject, I'll be glad.
Thanks.
First I would like to advise about one particular point about displaying multi-lingual content if your presentation is going to be same irrespective of language and locale. And that is...
You do not want to repeat your view/presentation code.
Your code could duplicate quite a lot and cause you some problem.
However if you really want to have them separate template I am thinking that your following line may have problem;-
url: '/{lang:' + Translate.getLangs() + '}/{products:' + Translate.getRouteVariants('products') + '}/{productSlug}',
If you use curly brace approach the text after : is actually a regular expression.
So you can't just return the getLangs() as 'en|ch' it should be something like
'[a-z][a-z]{en|ch}'
(I have not tested but should work.)
So I'm working on building a dynamic model for a project that reacts to data sent from an API. The api will return, among other things, what your location should be and this in turn becomes the url. So, eg:
{
location: 'xyz'
(...)
}
So currently my router will transition to the right route dynamically. But I still have to hardcode each route ( IndexRoute, LocationXYZRoute, LocationABCRoute, etc).
My goal is to create a single route that handles things dynamically. We'll call it App.LocationRoute and my routes would look something like:
App.Router.map(function() {
this.resource(':location', function() {
this.route(':subLocation')
}
}
Now, I have two architectural questions:
1) Whats a good way to handle this sort of dynamic routing? (I've read through the guide about dynamic routing using the ':post_id' type example, but I think I need a more holistic example to really grasp it.
2) The API sends back a whole host of other data as well. I want to add this to the route's model but I also have some other static models. Doing...
this.controllerFor(location).set('content', APIdata);
... works, but it does not set for routes currently using static models. I tried something like:
this.controllerFor(location).set('apiData', APIdata);
and...
this.controllerFor(location).set('model:apiData', APIdata);
... but neither worked.
Any suggestions?
1) Yes, you should use dynamic segment
this.resource('location', { path: '/location/:location_id' }, function() {
this.resource('sublocation', { path: '/sublocation/:location_id' });
});
2) Are you using ember-data? You could check sideloaded data. Anyway, you could read the json and set the payload of each entity for each specific route.
this.controllerFor('location').set('content', APIdata.location);
this.controllerFor('user').set('content', APIdata.user);
People could help you better, if you separate your questions and create a http://emberjs.jsbin.com/ with isolated each specific case?