Im trying to template some components often used in my project. To omit the introduced redundancy in html content. However i didnt figure it out if it is even possible to do so.
I have a template like:
<script type="text/x-jquery-tmpl" id="somefieldtemplate" >
<input name=" Prefix" type="text" data-bind="value: ${ $item.fieldName}SomeField" />
..... mor contents ...
</script>
The parameter bound to the input component shall be adjustable as someone may see via template options so i have an entry like
<div data-bind="template: { name: 'somefieldtemplate',
templateOptions:
{ fieldName:'somefield', displayName:'somefieldlabel' } }">
The error message in my console log is:
SyntaxError: Unexpected token {
I narrowed the problem down to the fact that if i remove $item.fieldName with its value it works.
Has anybody an enlightening solution to this problem maybe ?
Edit:
As information im currently using knockout.js in version: knockout-latest
I had the same problem and after struggling a lot, I solved it by moving to knockout 1.3 beta (now it's in RC) which doesn't use external templating engines. It doesn't support templateOptions either but that's not a problem. I just constructed a custom data for the template which contains the main data as a property plus other properties that contain the stuff I would have passed in templateOptions in 1.2. I passed it in the data parameter, and everything worked fine.
Try
data-bind="value: ${fieldName} + 'SomeField'"
Sadly i need to answer it myself. But i managed to get it working. Thanks to the tip of RP Niemeyer.
For everyone interested in this:
Observables are generated dynamically in the model someModel with a register component method. This observables have always names like <field>SomeField
Template:
<script type="text/x-jquery-tmpl" id="somefieldtemplate" >
<input name="${$item.fieldName}Prefix" type="text" data-bind="value: someModel[$item.fieldName + 'SomeField']" />
..... more contents ...
</script>
Template-Binding:
<div data-bind="template: { name: 'somefieldtemplate',
templateOptions:
{ fieldName:'somefield', displayName:'somefieldlabel' } }">
Related
I am using a custom-element with my Aurelia app. When I am binding data from my view-model with the custom-element, it is working fine. Even if I make some changes in the data in the custom-element control, the change is also reflected to the data in my view model, thanks to the two-way data binding.
However, if I make some changes in the data from the view model (using javascript), the data is not updated in the custom-element. I have replicated this problem for a simpler setting.
Simple View Model
export class Playground {
public testObj: any;
counter = 0;
constructor() {
this.testObj = {
prop1: "This is prop1 value"
, collection2: [{ id: "item21" }]
}
}
updateProp1() {
alert("before update: "+this.testObj.prop1);
this.testObj.prop1 = "Sayan " + this.counter++;
alert(this.testObj.prop1);
}
verifyChange() {
alert(this.testObj.prop1);
}
}
Simple View
<template>
<h1>
Playground
</h1>
<div >
<div repeat.for="item of testObj.collection2">
<div class="row">
<div class="col-sm-4">
<input type="text" class="form-control" placeholder="prop1"
value.bind="$parent.testObj['prop1']">
</div>
</div>
</div>
<button click.delegate="updateProp1()" class="btn btn-primary"> Update Prop1 </button>
<button click.delegate="verifyChange()" class="btn btn-primary"> Verify Change </button>
</div>
</template>
Now whenever I click Verify Change after changing the value in textbox, the changed value comes in the alert. But, if I click the Update Prop1 button, the prop1 value gets updated, but the change doesn't reflect in the view.
I am not sure exactly what I am missing.
Note: Instead of using $parent.testObj['prop1'], if $parent.testObj.prop1 is used, the databinding works as it should. However, my actual custom-element is of generic kind and the property name is not known before hand, hence it seems that I need to keep using $parent.testObj['prop1'] notation instead of dot notation: $parent.testObj.prop1.
At pointer/suggestion/feedback is appreciated.
Update: If anyone can point out the the difference between the dot notation and indexer notation w.r.t. aurelia data-binding (I have checked this already), that will be of great help.
This was an issue in earlier builds of the aurelia/binding module. Here's the related issue(s):
https://github.com/aurelia/binding/issues/75
https://github.com/aurelia/binding/pull/76
I tried your view/view-model in the latest version of aurelia and everything worked. Here's a screencast of what I saw: http://screencast.com/t/KqcuqXWjkU2
Make sure you have the latest version of the aurelia components installed- update steps here: http://blog.durandal.io/2015/05/01/aurelia-may-status-and-releases/
I currently have a partial HTML that is being routed to, with a template and a custom Controller. The code snippet in my Angular template I would like to get working is:
<input type="text" typeahead=val for val in getValue($viewValue)>
However, it never enters into the function getValue(), while all other functions in my controller seem to be okay. When I take the typeahead out of the Angular template/partial, it seems to work. Why is this and how do I fix it?
You need to have an ng-model attribute to use the typeahead directive from AngularUI, even if you don't need to bind it to anything.
Change your markup to similar to the following:
<input type="text" ng-model="typeaheadVal" typeahead="val for val in getValue($viewValue)">
I am trying to use Knockout-ES5 along side Knockout in my project. But it seems to not working at all. Here is a very simple sample taken from the official Knockout tutorials. Here is my markup code
<p>First name: <input data-bind="text: firstName" /></p>
<p>Last name: <input data-bind="text: lastName" /></p>
And here is my js file
$(function () {
var obj = {
firstName: 'Bert',
lastName: 'Bertington'
}
ko.track(obj);
obj.firstName.subscribe(function(v){
alert(v);
});
});
The line obj.firstName.subscribe(function) crashes with the exception
"Object doesn't support property or methode 'subscribe' (IE10). I cannot seem to understand why this error. Here are the js files am using:
<script src="scripts/jquery-2.1.1.js"></script>
<script src="scripts/knockout-2.debug.js"></script>
<script src="scripts/weakmap.js"></script>
<script src="scripts/knockout-es5.js"></script>
I have tried various combinasions: e.g
ko.track(obj);
ko.applyBindings(obj);
but still nothing. Any suggestion toward the right direction would be very much appreciated. Thank you/
I have not used ko es5 but had a quick look at their documentation.
Looks like you need to use a method to get hold of the underlying observable:
Accessing the observables
If you want to access the underlying
ko.observable for a given property, e.g., so that you can subscribe to
receive notifications when it changes, use ko.getObservable:
ko.getObservable(someModel, 'email').subscribe(function(newValue) {
console.log('The new email address is ' + newValue); });
http://blog.stevensanderson.com/2013/05/20/knockout-es5-a-plugin-to-simplify-your-syntax/
I have an app with many forms. Each field has several HTML elements, so I thought I could extract some directives (one per type of field) to keep my forms tidy.
I've created a sample app to demonstrate the problem, but I'm getting inconsistent behavior. In the sample app, a <link /> element replaces the <input />. In my real app, <input /> just gets removed from the DOM completely. I feel like this should be easy; why doesn't it work?
To answer your stated question, it's because you told it to, with ng-transclude. That replaces the contents of the tag with the original element, which I don't think you wanted; you probably wanted the original contents to be transcluded as the label instead.
This is probably what you're looking for:
<div class="form-group" >
<label for="{{htmlId}}" ng-transclude></label>
<input id="{{htmlId}}" class="form-control" type="text" ng-model="model" />
<span ng-repeat="error in errors">{{error}}</span>
</div>
I've moved the tranclusion into the label. While this works, I would also recommend the style of actually passing a label attribute, rather than transclude it, just for the sake of having a consistent API and simpler code; it's functionally equivalent, though, so don't let me bully you.
Also, you've got a few errors in your .js as well. First, you want to use = in your scope instead of &
scope: {
model: '=',
errors: '='
},
& is used to pass methods, while = is used for objects (this is a simplification). Since your model and errors are objects, you'll want to use = instead.
Finally, in your example, your html template and your directive's template don't have the same name... you've got an extra 's' in your .js, but that's probably just in the plunker and not your real app.
I'm exploring the Meteor-framework. I've a lot of experience with Java EE / JavaServer Faces (JSF), but I'm new to JavaScript-development. I'm trying to create a nicely formatted "horizontal form", as described at http://twitter.github.io/bootstrap/base-css.html#forms. My problem is, that this gives me a lot of repeated HTML for each input field, which is not DRY...
So, I'm trying to create a construct like "composite components" in JSF 2.x. This means I'm looking for a way to call a Meteor-template and substitute some values in it.
My template is like this:
<template name="formField">
<div class="control-group">
<label class="control-label" for="{{this.id}}">{{this.label}}:</label>
<div class="controls">
{{this.formField}}
</div>
</div>
</template>
I was able to get it partially working, by calling it like this:
{{> formField labels.x}}
Where I defined the labels map like this:
Template.myTemplate.labels = {
"x": {id: 'idx', label: 'labelx'},
"y": {id: 'idy', label: 'labely'},
"z": {id: 'idz', label: 'labelz'}
}
The problem is, of course, substituting the <input>-element in the template. I tried all sorts of ways to do this, but there are several problems:
I could add the <input>-element to my formField-template, but then I cannot bind the value of that <input>-element to a property of the JavaScript-object that is being edited in the form.
I could create a function that returns an <input>-element, but then I would end up with markup-code in my JavaScript-sources.
Another problem is that I'm not really satisfied with the Template.myTemplate.labels-map. It seems this is unavoidable, since I was not able to use any literal values. It would be nice if I was able to call the template like this:
{{> formField idx labelx}}
{{> formField idy labely}}
{{> formField idz labelz}}
To conclude, I have basically one question: what's the best way to create some sort of component with Meteor/Handlebars?
Forms are on the roadmap:
https://trello.com/card/easy-forms/508721606e02bb9d570016ae/8
But in particular check out this discussion:
https://github.com/meteor/meteor/issues/1054 (from the above link).
As for creating components in Meteor, there is no the way to do it, but you might want to check out how the accounts packages work, as that's pretty isolated, extensible, and a form:
https://github.com/meteor/meteor/tree/master/packages