Polymer 1.4 dom-bind defining properrties - data-binding

In the index.html I use:
<template is="dom-bind" id="app">
In a normal dom-module I use:
<script>
(function() {
'use strict';
Polymer({
is: 'my-xxxx',
properties: {
/* location for properties */
}
Where do I define the properties used in the template dom-bind (f.i to have an observer attached to them?

Based on Polymer docs, you'd use JavaScript (inline or imported in index.html) to add template properties inside of an event handler for the template's dom-change event. For example, you could add a message property to the template with this script:
var t = document.getElementById('app');
t.addEventListener('dom-change', function() {
t.message = 'Hello world!';
});
See demo below:
<head>
<base href="https://polygit.org/polymer+:master/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<template is="dom-bind" id="app">
{{message}}
</template>
<script>
var t = document.getElementById('app');
// The dom-change event signifies when the template has stamped its DOM.
t.addEventListener('dom-change', function() {
// auto-binding template is ready.
t.message = 'Hello world!';
});
</script>
</body>
jsbin

Related

How to use Polymerfire to fetch data from a Firebase

Description
My goal is to use the polymerfire element to send a request to a Firebase endpoint to detect if there is data there and, if so, its content.
Please include in your answer a working demo if possible and extra points if you point to some good documentation as the current documentation is insufficient.
Expected outcome
I expect the demo page to look like:
CLICK ME
ornithischia
foo bar baz
And when the CLICK ME button is pressed, the following to appear in the console:
"You clicked me!"
"triceratops"
"{appeared: -68000000, height: 3, length: 8, order: "ornithischia", vanished: -66000000, weight: 11000}"
Actual outcome
The the demo page looks like:
CLICK ME
foo bar baz
And when the CLICK ME button is pressed, the following actually appears in the console:
"You clicked me!"
"triceratops"
"{}"
Live Demo
http://jsbin.com/fasovaxonu/1/edit?html,console,output
<!doctype html>
<head>
<meta charset="utf-8">
<!-- Source: https://github.com/Download/polymer-cdn -->
<base href="https://cdn.rawgit.com/download/polymer-cdn/1.7.0.2/lib/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymerfire/polymerfire.html">
<link rel="import" href="paper-button/paper-button.html">
</head>
<body>
<dom-module id="x-element">
<template>
<style></style>
<firebase-app name="my-app"
auth-domain="dinosaur-facts.firebaseapp.com"
database-url="https://dinosaur-facts.firebaseio.com/"
>
</firebase-app>
<p>
<paper-button on-tap="_onTap">Click Me</paper-button>
</p>
<!---->
<firebase-query
app-name="my-app"
path="https://dinosaur-facts.firebaseio.com/dinosaurs"
data="{{dinosaurs}}"
>
</firebase-query>
<firebase-document
app-name="my-app"
path="https://dinosaur-facts.firebaseio.com/dinosaurs/triceratops"
data="{{triceratops}}"
>
</firebase-document>
[[triceratops.order]]
<br /><br />
<template is="dom-repeat" items="[[dinosaurs]]">
[[item.order]]
</template>
<template is="dom-repeat" items="[[test]]">
[[item]]
</template>
<!---->
</template>
<script>
(function(){
Polymer({
is: "x-element",
properties: {
dinosaurs: Array,
test: {
value: function() {
return ['foo', 'bar', 'baz'];
}
},
},
_onTap: function() {
console.log('You clicked me!');
console.log('triceratops', JSON.stringify(this.triceratops));
}
});
})();
</script>
</dom-module>
<x-element></x-element>
</body>
You first need to include <firebase-app> to initialize firebase.
<firebase-app
database-url="dinos-89701.firebaseio.com"
api-key="AIzaSyDLkCy3RNC5uFomEjVsLUehpzKFDrfAplU"
auth-domain="dinos-89701.firebaseio.com">
</firebase-app>
Get your api-key here:
https://console.firebase.google.com/project/YOUR_PROJECT/settings/general/
Demo:
http://jsbin.com/joxatuz/1/edit?html,console,output

Backbone view on button not rendering

I've just started out using backbone. I want to apply a view to a button, but when I open my file in the browser there is nothing there.
Why isn't the button being rendered?
HTML:
<!-- Scripts -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script type="text/javascript" src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<script type="text/javascript" src="views/BaseButtonView.js"></script>
</head>
<body>
<script type="text/template" id="button-test">
<div id="test-buttons">
<button class="cta-ajax">
<p>send message</p>
<div class="spinner-container"></div>
</button>
</div>
</script>
</body>
</html>
View:
$(document).ready(function(){
var ButtonView = Backbone.View.extend({
el: $(".cta-ajax"),
template: _.template($("#button-test").html()),
initialize: function(){
console.log("Started!");
},
render: function() {
this.$el.html(this.template());
console.log("rendered");
return this;
}
});
var TView = new ButtonView();
});
You have two issues with your code. Here is a working jsfiddle: http://jsfiddle.net/cj4zkyow/1/
Issue 1:
Aside from implementing the initialize function, you also need to call render within initialize. Otherwise you have to call render manually.
Issue 2:
Second issue is that you set the el attribute of your view to .cta-ajax, but the element does not exist. It is part of your template. The el attribute is the element that your view gets appended to. So you need to use something that exists in the DOM.
HTML:
// Need a element to append view to.
<div id="test"></div>
<script type="text/template" id="button-test">
<div id="test-buttons">
<button class="cta-ajax">
<p>send message</p>
<div class="spinner-container"></div>
</button>
</div>
</script>
Javascript:
$(document).ready(function(){
var ButtonView = Backbone.View.extend({
// If you specify, el, it should be an element in the DOM, not in your template.
el: $("#test"),
template: _.template($("#button-test").html()),
initialize: function(){
// Need to call render in initialize function to render view.
this.render();
},
render: function() {
this.$el.html(this.template());
return this;
}
});
var TView = new ButtonView();
});

Basic angularjs code not working properly

Have installed the angularjs and Twitter.Bootstrap packages succesfully
This is my index.html:
<!DOCTYPE html>
<html ng-app="TodoApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="Scripts/jquery-1.9.1.js"></script>
<script src="Scripts/bootstrap.js"></script>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
<script src="Scripts/app.js"></script>
<link rel="stylesheet" type="text/css" href="Content/bootstrap.css" />
<title>Amazing Todo</title>
</head>
<body>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>
This is my app.js:
var TodoApp = angular.module("TodoApp", []).
config(function ($routeProvider) {
$routeProvider.
when('/', { controller: ListCtrl, templateUrl: 'list.html' }).
otherwise({ redirectTo: '/' });
});
var ListCtrl = function ($scope, $location) {
$scope.test = "testing";
};
And, this is my list.html:
<h1>Test: {{test}}</h1>
This should work fine. However the index.html is not showing the content of list.html. I think the angularjs part is not working properly.
No idea about what am i doing wrong?
Once you have defined a module, you need to define your controllers for that module and not independently.
Thus, your controller should be rewritten as:
TodoApp.controller('ListCtrl', [ '$scope', '$location',
function ($scope, $location) {
$scope.test = "Testing";
}
]);
This should show the view in question.
I would say, that if you check errors in console (in Chrome or IE press F12) you should see:
...Failed to instantiate module TodoApp due to:
Error: [$injector:unpr] Unknown provider: $routeProvider...
The reason for this expectation is that we ask IoC to inject $routeProvider while not correctly listing dependent modules. This is the above code:
var TodoApp = angular
// here we say: we do not need any other module
.module("TodoApp", [])
// here we ask: inject $routeProvider from other module
.config(function ($routeProvider)
So to make it runing we have to include the module 'ngRoute'
var TodoApp = angular
// here we say: we need these modules to make our module working properly
.module("TodoApp", [
'ngRoute'
])
// now we can ask for the provider,
// using minification-safe syntax
.config(
[ '$routeProvider',
function ($routeProvider) {
$routeProvider.
...
}]);
And also do not forget to also reference this module scripts:
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
<!-- here we have to load this module -->
<script src="Scripts/angular-route.js"></script>
What is your directory structure can you check if list.html is in the same directory as index.html, if not specify a relative path from the application root?
Since no one has posted a full correct answer to this question and it hasn't been closed yet, here is another answer.
This is your function:
var ListCtrl = function ($scope, $location) {
$scope.test = "testing";
};
This is a bare function, which isn't of much use. You need a controller so that Angular knows what to do with {{ test }}:
<div ng-controller="someController">
<h1>{{ test }}</h1>
</div>
If you insist on keeping the function as a separate variable, you could do so and still have a controller:
var ListCtrl = function ($scope, $location) {
$scope.test = "testing";
};
TodoApp.controller('someController', ListCtrl);
This also works.
Despite of this, your UI won't show, as there's an error in it:
var TodoApp = angular.module("TodoApp", [])
You're using $routeProvider and .when(),.otherwise(), for which you need ngRoute as a dependency:
var TodoApp = angular.module("TodoApp", ['ngRoute'])
Your app should work after that.

Can handlebars walk up while iterating through lower level items?

With the latest stable version of Handlebar, I'm trying to display the site name while iterating through each children. The output of the code below is:
5
Stackoverflow
One -
Two -
Can handlebars retrieve the site name by walking up while rendering the children?
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script src="handlebars.js"></script>
<script>
$(document).ready(function() {
var source = $('#entry-template').html();
var template = Handlebars.compile(source);
var context = {
site: {
age: 5,
name: 'Stackoverflow',
children: [
{
name: 'One'
},
{
name: 'Two'
}
]
}
};
$('div#output').html(template(context));
});
</script>
</head>
<body>
<div id="output"></div>
<script id="entry-template" type="text/x-handlebars-template">
<div>{{site.age}}</div>
<div>{{site.name}}</div>
{{#each site.children}}
<div>{{name}} - {{site.name}}</div>
{{/each}}
</script>
</body>
</html>
Try doing {{../site.name}} in your loop. The ../ Handlebars syntax allows access of the parent scope.

jsView - How to render the content of a custom tag with its props as its data?

I have custom tag which can have itself as an inner tag and I want to bind it its props as data. I can change the first test tag title property and see the change but cannot do that for the inner test tag. I think it is because of the wrong arguments of this.tagCtx.content.render(). Below is the example:
<!DOCTYPE html>
<html>
<head>
<script src="js/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="js/jsrender.js" type="text/javascript"></script>
<script src="js/jquery.observable.js" type="text/javascript"></script>
<script src="js/jquery.views.js" type="text/javascript"></script>
<script id="testTemplate" type="text/x-jsrender">
<div>{^{>title}}{^{:content}}</div>
</script>
<script id="myTemplate" type="text/x-jsrender">
{^{test title='Test1'}}
{^{test title='Test2'}}
{{/test}}
{{/test}}
</script>
<script type="text/javascript">
$.views.tags({
test: {
render: function(){
this.tagCtx.props.content = this.tagCtx.content.render();
return this.template.render(this.tagCtx.props, this.tagCtx, this.tagCtx.view);
},
template: "#testTemplate"
}
});
$.templates({myTemplate: "#myTemplate"});
$(function () {
$.link.myTemplate('#container', {});
$('#editTitle').click(function () {
$.observable($.view('#container div:first div').data).setProperty('title', prompt());
});
});
</script>
</head>
<body>
<span id="editTitle">EditTitle</span>
<div id="container"></div>
</body>
</html>
The problem here is that the inner tag is being rendered as a string, not as a data-linked tag, since the this.tagCtx.content.render() call is simply calling the render method on the compiled template corresponding to the block content.
If you want to render as a data-linked tag, you need to call this.tagCtx.render().
In addition, in calling this.tagCtx.render() you need the tag to render its content, and not another template. Setting template: "#testTemplate" will cause the tag to use that template instead of the content. So what you need is something along these lines:
var template = $.templates("#testTemplate");
$.views.tags({
test: {
render: function() {
var tagCtx = this.tagCtx;
tagCtx.props.content = tagCtx.render();
return template.render(tagCtx.props, undefined, tagCtx.view);
}
}
});
You probably don't want to pass in tagCtx as context in the template.render(...) call. You can pass in tagCtx.ctx, or simply undefined...

Resources