Using Vue dynamic route name, in component function - javascript

I've been trying to make a dynamic view rendering, with Vue and Laravel. However, i can't wrap my head around how i am supposed to parse the dynamic parameter, to the component function.
Router.map({
'/cms-admin/:page': {
component: {
template: returnView(this.$route.params.page)
}
}
});
function returnView (option) {
// Generate the AJAX request here
}
Through documentations i've read, that $route should solve the issue. I can parse $route into the view, and print the text on the page. However, i can't use $route inside the map, to get the dynamic name?
Say, i enter "/cms-admin/dashboard", 'dashboard' should get parsed down to the template parameters.
Thanks in advance,
Steven

register the individual templates for the pages as partials v1 v2
use <partial> and $route
js:
component: {
template: '<partial :name="partial" v-if="partial !== ''"></partial>',
data() { return { partial: '' } },
ready() { this.partial = this.$route.params.page},
}
Note: Not sure whether you can access this.$route in data(), therefore I used the ready() event, but maybe you can drop that and put it directly in data().

Related

Safe navigation at v-model directive in Vue.js

For example we have the following input component:
<input type="text" v-model="example.modules.report.description.title"></input>
Full source
I don't want to define in data following object:
example: {
modules: {
report: {
description: {
title: ""
}
}
}
}
I anticipate that Vue.js will create that structure itself (just like Angular.js), but it doesn't do it.
Is there any way to solve this problem?
the data() method is a factory that initializes the model on which the component is bound.
The docs explains clearly how is supposed to make it work
You should declare the initial value on the JavaScript side, inside the data option of your component.
vuejs docs
If your model is so complex to require all these nested compositions maybe you have to be fine with it or design a different data model.......or create your model with your own factory
export default {
data : example()
}

Rendering custom nested html in Vue.js

I'm moving a site from AngularJS 1.x that relies heavily on the $compile service (which is no longer available in Angular 2.x. In the application I have a directive that looks something like this <myDir elemId="someRestEndPointID"></myDir>
and does the following:
1) A http call is made and the response returns a string that contains a directive <myDir elemId="someRestEndPointID"></myDir>
2) A call is made to the server to for /someRestEndPointID
3) Angular gets the content and renders and looks for another <myDir> tag
4) the process is repeated (recursive)
I have not yet found something that does this for our new framework Vue.js. Is there a similar feature or library that would achieve this logic in Vue.js?
That seems like a convoluted way to work and I wouldn't follow that pattern. Why not create a component that takes an endpoint as a property <your-component endpoint="https://example.org/"></your-component> and then component will do the call inside the create method?
<template>
<div>
<img src="loading.jpg" v-show="loading" />
<!-- Content here -->
{{content}}
</div>
</template>
<script>
export default {
props: ['endpoint'],
data() {
return {
loading: true,
content: null
};
},
created() {
this.$http.get(this.endpoint).then(resp => {
this.content = resp.body;
this.loading = false;
});
}
}
</script>

Adding new keys generated by a variable to a object in Vue

Building a project using Vue.js (and Laravel), the following (greatly simplified) code results in the below error:
Vue component:
<template>
<input type="text" class="form-control" v-model="main_object[item_id][my_answer_key]">
</template>
<script>
export default {
props: [
],
data() {
return {
main_object: {},
item_id: '1234',
my_answer_key: '5678'
}
},
ready: function () {
vm = this;
},
methods: {
}
}
</script>
Error received:
We know you can use the vm.$set() method to add properties to the object. However, we’re building the model path on the fly (item_id and my_answer_key change depending on various user options being selected). It seems like we have to write a method that determines if the object property is already set, and if it's not set, to then set it. Is there a better way to accomplish the above?
You could seemingly get around this by using the created hook and $set:
created: function () {
this.$set(this.item_id + "." + this.my_answer_key, "")
}
However, if item_id and my_answer_key can change, this approach will ultimately not work because Vue does not have dynamic two way binding. In other words, the binding in your v-model will be created once and will not change later if either of the item_id or my_answer_key values change.
So, to accomplish something like this, you might need to resort to a kludge like using a v-if and toggling it to destroy and recreate the input (and it's binding). That might work.
Sometimes, computed's can help with these situations. Bind your input to a simple attribute on your data model and use a computed to generate the actual nested data model you need elsewhere.

What is the difference between a ractive template, partial and component

I've built a ractive.js app using partials. These partials are loaded via fetch/ajax - and all works nicely.
I then decided I wanted to encapsulate data along with the partial so looked at components - as I understood a component to do just that: Isolate a template/partial with its data.
I then looked to load the components in: http://ractivejs.github.io/ractive-load/
However, I don't really see the advantage of this approach - as it appears with the loader you can only load in the components template, not the entire encapsulated component (data, templates etc). You still have to put the data onto the main ractive instance (as you would with a partial).
I'm trying to dyanamically update the component. I'm also using page.js for routing. I'm trying to separate out all the concerns.
I'm probably not explaining myself very well - here is my code... most of it was taken from martydpx's answer here How to create Ractive's subcomponents dynamically and change them programmatically )
....
<dynamic name='{{name}}'/>
</script>
<script>
// Component loader
Ractive.load({
home: '/components/home.html', // seems this can only contain a template. Is it possible for it to contain everything - data and all?
packs: '/components/packs.html',
....
addplayer: '/components/addplayer.html',
notfound: '/components/notfound.html',
}).then( function ( components ) {
Ractive.components[ 'home' ] = components.home;
Ractive.components[ 'packs' ] = components.packs;
....
Ractive.components[ 'addplayer' ] = components.addplayer;
Ractive.components[ 'notfound' ] = components.notfound;
// dynamically load component based on route
Ractive.components.dynamic = Ractive.extend({
template: '<component/>',
components: {
component: function() {
this.set('foo','bar'); // I can dynamically set the data here.. but how would I add defaults for each component, within the component?
return this.get('route');
}
},
oninit: function(){
this.observe('route', function(){
this.reset();
},
{ init: false}
);
}
});
var r = new Ractive({
el: document.body,
template: '#template',
data: {
route: 'home'
}
});
// Routing. Sets the route... which triggers the component
page('/', index);
...
page();
function index() {
console.log('index');
r.set('route','home')
}
EDIT
I've read this - which has been a great help :)
https://github.com/ractivejs/component-spec/blob/master/authors.md
In the dynamic component scenario - how would I dynamically update component specific data. I seem to be able to do it when the component tag is hardwired into the page... but not when the component tag is dynamically created. After much playing about in the console - its as if it doesn't see the dynamic component. So things like r.findComponent('home').get() don't work.
Yet, if I put a <home/> tag in the template - it does work.
Also, do components automatically 'tear down' when they're un-rendered?
I'm not 100% sure what you are looking for.
First you create a child component -
var MyWidget = Ractive.extend({
template: '<div>{{message}}</div>',
data: {
message: 'No message specified, using the default'
}
});
You register this with Ractive runtime
Ractive.components.widget = MyWidget;
Then you create a parent component
var Parent = Ractive.extend({
template: '<div>
<MyWidget message={{widget}} />
</div>'
});
You use the parent instance to pass the data to child
// Live instance of parent
new Parent({
el: 'id',
data : {
widget: {
message : 'Waddup kiddo'
}
}
});
data.widget gets mapped to MyWidget's data, in-turn gets the message data.
For more info refer this
Generally there are 3 types of components you will be creating & using -
Self-sufficient Components - It knows everything it needs to know by itself. You don't pass anything to it. It creates it's own data or knows where to get it from. Ex: A logo component which knows by itself where to get the image from.
Dumb Components - They have no intelligence and all the data that it needs should be passed from parent. Like in our example - MyWidget has no idea where and what message stands for. Just renders it. No questions asked. Parent will fetch message and just pass it on.
Smart Components - Components which do some heavy lifting. An example would be Profile component. Parent will pass just a profileID to this, and it knows where to get profile data from, does some ajax calls, knows how to parse and interpret the data, may be even starts a socket and listens to changes etc.
So you decide how you want to make your components, who takes responsibility and think about data-encapsulation then.

How can I reuse/dry these routes in ember.js

I have these routes
this.resource('politicians');
this.resource('politician', { path: '/politicians/:politician_id', function () {
// Non nested interface so non nested politician route.
this.resource('questions', function () {
this.resource('question', { path: ':question_id' });
});
});
this.resource('questions', function () {
this.resource('question', { path: ':question_id' });
});
I'd like the question route to be rendered anywhere (using a modal) in the app without losing the current context, but still have a specific/unique url for each question, knowing that the question you got from the nested questions route and the non nested ones are the same.
this.resource('question', { path: ':question_id' });
The thing is that I don't want to make a custom outlet for that because then I won't have a url for each question.
This sort of problem is best solved by using query-params and hooking up the modal based on params. If you don't want to do that you're really stuck with building questions into each route if you want it to be URL based.
Here's an example: http://emberjs.jsbin.com/ucanam/3566/edit
What you're looking for is Ember's {{render}} helper. Simply place a {{render 'question' questionModel}} inside the modal you wish to use.
You can learn about the render helper here
EDIT:
Here is a jsbin to show the basic idea of how to use a render tag in this way. This jsbin renders the same template in 2 different ways; Once tied to a route url and once by using the render helper.
jsbin here

Categories