Vue.js watched data chang twice with only one request - vue.js

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="app">
<div class="layui-input-block" style="width:510px;">
<form class="layui-form" action="">
<select v-model="form.entrCode">
<option value="">please select an entry</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</form>
</div>
</div>
</body>
</html>
<script src="//cdn.bootcss.com/vue/2.2.4/vue.min.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
action: '',
form: {
entrCode: '',
}
},
watch: {
action: function (val) {
if (val !== "add"){
var vm = this;
//$.get("/park/GetLEDDtl", { areaId: vm.form.code }, function (rs) {
// vm.form = rs;
//}, "json");
//simulate setting on ajax.success
vm.form = { "entrCode": "20" };
}
},
"form.entrCode": function (val, old) {
alert("【entryCode changed】 new:" + val + " old:" + old);
}
},
created: function () {
this.action = "edit";
}
});
</script>
Please look at my code. I've only set app.form = object once, why there are two value changed be watched?
First, it changes from '' to '20', which is what I'm expected, but suddenly it changes from 20 to undefined.
(The code patsed I commented ajax request, and set value directly.)
What just happened?

There is no option with the value you are setting the variable to. The select object cannot be synced up to show the value, so it reverts the value to undefined.

Related

Same vue code from html not working in blade file

below is the code from html:
<div id="app">
<select #change="onSelectUserType()" v-model="type">
<option value="">Who are you?</option>
<option value="tailor">Tailor</option>
<option value="store">Store</option>
<option value="customer">Customer</option>
</select>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script>
new Vue({
el: "#app",
data: {
type: ''
},
methods: {
onSelectUserType: function () {
console.log(this.type)
alert(this.type)
}
},
mounted() {
console.log('mounted');
}
});
</script>
this is code from html that is working, when i apply it inside blade it is not working! it should show alert and console on changing the options, but nothing is visible, also no error is detected what is the issue?

VueJS Filter Not Working

Why does filter do not work?
Error says: [Vue warn]: Failed to resolve filter: uppercase.
Not sure why but filter is not working.
Also, is this the best way to code this functionality? Are there any ways to do this, or the suggested ways? I'm not sure about using the $refs, maybe I can do this simpler, but with effective use of reusable components.
I'm trying to emulate an Ajax Response by using random message and status instead.
Link: JSBIN
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="app">
<login-alert ref="refalert"></login-alert>
<p>
<button #click="showme">Random Alert</button>
</p>
</div>
<script src=" https://unpkg.com/vue"></script>
<template id="template-alert">
<div v-if="showAlert">
<div :class="'alert alert-'+alertType+' alert-dismissible'" transition="fade">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true" v-on:click="close">×</button>
<h4>{{title|uppercase}}!</h4>
{{message}}
</div>
</div>
</template>
<script>
Vue.component('login-alert', {
template: '#template-alert',
data: function() {
return {
alertType : null,
title : null,
message : null,
showAlert : false
}
},
methods: {
close: function() {
this.alertType= null;
this.title= null;
this.message= null;
this.showAlert= false;
},
open: function(type, message) {
this.alertType= type;
this.title = type;
this.message= message;
this.showAlert= true;
}
}
});
var app = new Vue({
el: '#app',
methods: {
showme: function() {
var randomStatus = ['error', 'warning', 'success'];
var randomMessage = ['Lorem Ipsum', 'Adolor Sit Amet', 'Abed Meepo'];
var status = randomStatus[Math.floor(Math.random() * randomStatus.length)];
var message = randomMessage[Math.floor(Math.random() * randomMessage.length)];
this.$refs.refalert.open(status,message);
}
}
});
</script>
</body>
</html>
The uppercase filter has been removed in Vue.js 2.
https://v2.vuejs.org/v2/guide/migration.html#Built-In-Text-Filters-removed
You can simply use:
{{ text.toUpperCase() }}
As far as the structure of your code goes, something like this is probably better off in a method:
close: function() {
this.alertType= null;
this.title= null;
this.message= null;
this.showAlert= false;
}
Since you are duplicating it twice but just with different values.

KoGrid not displayed when Select also on page

I have an ASP.Net MVC4 website. Here's the problem view:
#model TVS.ESB.BamPortal.Website.Models.MyTasksViewModel
#using System.Web.Script.Serialization
#{
ViewBag.Title = "My Tasks";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>#ViewBag.Title</h2>
#{ string data = new JavaScriptSerializer().Serialize(Model); }
<div id="Knockout">
#* When select added thenKoGrid does not display! <select class="form-control" data-bind="options:users, optionsText: 'AdLoginId', value:selectedUser" />*#
<div id="Buttons">
<span>Reassign to User: <input class="form-control" data-bind="text:username"/></span>
<button class="btn-default" data-bind="click:promoteState">Promote State</button>
<button class="btn-default" data-bind="click:reassignTasks">Reassign Task(s)</button>
</div>
<div id="KoGrid" data-bind="koGrid: gridOptions" />
</div>
#section Scripts {
<script src="~/KnockoutVM/Mytasks.js"></script>
<link rel="stylesheet" type="text/css" href="~/Content/KoGrid.css">
<script type="text/javascript">
var vm = new ViewModel(#Html.Raw(data));
ko.applyBindings(vm, document.getElementById("Knockout"));
</script>
}
I have commented out the select that gives the problem. If I leave this in, then it displays fine, including the items from the observeable array I'd expect. However, for some reason the KoGrid is then not displayed. If I remove the Select then the KoGrid displays just fine. I've tried refreshing with the Google dev tool console window open but no errors are reported. Any ideas why?
Here are relevant parts of the knockout view model:
function ViewModel(vm) {
var self = this;
this.myData = ko.observableArray(vm.Recs);
this.selected = ko.observableArray();
this.users = ko.observableArray(vm.Users);
this.selectedUser = ko.observable("");
this.username = ko.observable("");
this.rows = ko.observableArray(vm.Recs);
this.gridOptions = {
data: self.myData,
enablePaging: true,
pagingOptions: self.pagingOptions,
filterOptions: self.filterOptions,
selectWithCheckboxOnly: true,
selectedItems: self.selected,
canSelectRows: true,
displaySelectionCheckbox: true,
columnDefs: [{ field: 'Timestamp', displayName: 'Timestamp', width: 130 },
{ field: 'State', displayName: 'State', width: 70 },
{ field: 'FaultApplication', displayName: 'Application', width: 110 },
{ field: 'FaultExceptionMessage', displayName: 'Exception Message', width: 400 },
{ field: 'FaultServiceName', displayName: 'ServiceName', width: 140 },
{ field: 'LinkToFaultsPage', displayName: 'Link to Fault', width: 80, cellTemplate: '<a data-bind="attr: { href: $parent.entity.LinkToFaultsPage}" >Fault</a>' }
]
};
};
Your KOGrid is not displayed because your HTML is invalid:
The select tag cannot be self-closing see also on MDN.
So you need to always write out the closing tag </select>:
<select class="form-control"
data-bind="options:users,
optionsText: 'AdLoginId', value:selectedUser">
</select>
Otherwise the HTML is invalid and Knockout cannot interpret it properly.
I was able to work-around by moving the select list to a separate div and using the ko.applyBindings twice:
<div id="ControlPanel">
<select class="form-control" data-bind="options:users, optionsText: 'AdLoginId', value:selectedUser" />
<div id="Buttons">
<span>Reassign to User: <input class="form-control" data-bind="text:username" /></span>
<button class="btn-default" data-bind="click:promoteState">Promote State</button>
<button class="btn-default" data-bind="click:reassignTasks">Reassign Task(s)</button>
</div>
<div id="KoGrid" data-bind="koGrid: gridOptions" />
</div>
#section Scripts {
<script src="~/KnockoutVM/Mytasks.js"></script>
<link rel="stylesheet" type="text/css" href="~/Content/KoGrid.css">
<script type="text/javascript">
var vm = new ViewModel(#Html.Raw(data));
ko.applyBindings(vm, document.getElementById("ControlPanel"));
ko.applyBindings(vm, document.getElementById("KoGrid"));
</script>
}

Polymer 1.0 dynamically add options to menu

Hi I am having some trouble getting a menu to add options dynamically. They idea is the selection of the first menu decides what the second menu contains. I have built this before successfully without polymer. And it semi-works with polymer. dropdown one gets its content from json based on the selection, dropdown two gets its content also from a json. This part works, the issue is when you make a selection from dropdown one and then change it, dropdown two doesn't delete the old selection. I got this working last time with a function that first deletes all dropdown two's children before repopulating the content. Issue with Polymer is once the childNodes are deleted the dropdown breaks and no other children can be added via data binding. tried adding native with plain JS which populates the menu but the children are not selectable(from what I have read this might be a bug). Also I believe data binding on dynamic items also doesnt work anymore. anyway here is what I have:
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/paper-material/paper-material.html">
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="../../../bower_components/paper-menu/paper-menu.html">
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
<link rel="import" href="../../../bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../../bower_components/iron-dropdown/demo/x-select.html">
<dom-module id="add-skill">
<template>
<paper-material elevation="1">
<paper-dropdown-menu id="ddMenu" attr-for-selected="value" >
<paper-menu class="dropdown-content" id="vendorSelect" on-iron-select="_itemSelected">
<template is="dom-repeat" items="{{vendorList}}">
<paper-item id="vendorName" value="item">[[item]]</paper-item>
</template>
</paper-menu>
</paper-dropdown-menu>
<paper-dropdown-menu>
<paper-menu class="dropdown-content" id="certificationSelect" on-iron-select="_itemSelected">
</paper-menu>
</paper-dropdown-menu>
<!-- testing ideas -->
<paper-dropdown-menu>
<paper-menu class="dropdown-content" id="test" on-iron-select="_itemSelected">
<option extends="paper-item"> Option </option>
<option extends="paper-item"> Option1 </option>
<option extends="paper-item"> Option2 </option>
</paper-menu>
</paper-dropdown-menu>
<paper-button on-click="_deleteElement">
Delete
</paper-button>
</paper-material>
<iron-ajax
id="vendorSubmit"
method="POST"
url="../../../addskill.php"
handle-as="json"
on-response="handleVendorResponse"
debounce-duration="300">
</iron-ajax>
<iron-ajax
id="certificationSubmit"
method="POST"
url="../../../addskill.php"
handle-as="json"
on-response="handleCertificationResponse"
debounce-duration="300">
</iron-ajax>
</template>
<script>
Polymer({
is: 'add-skill',
ready: function() {
this.sendVendorRequest();
this.vendorList = [];
this.certificationList = [];
},
sendVendorRequest: function() {
var datalist = 'vendor=' + encodeURIComponent('1');
//console.log('datalist: '+datalist);
this.$.vendorSubmit.body = datalist;
this.$.vendorSubmit.generateRequest();
},
handleVendorResponse: function(request) {
var response = request.detail.response;
for (var i = 0; i < response.length; i++) {
this.push('vendorList', response[i].name);
}
},
vendorClick: function() {
var item = this.$;
//var itemx = this.$.vendorSelect.selectedItem.innerHTML;
//console.log(item);
//console.log(itemx);
},
sendCertificationRequest: function(vendor) {
var datalist = 'vendorName=' + encodeURIComponent(vendor);
console.log('datalist: ' + datalist);
this.$.certificationSubmit.body = datalist;
this.$.certificationSubmit.generateRequest();
},
handleCertificationResponse: function(request) {
var response = request.detail.response;
//var vendorSelect = document.getElementById('vendorSelect');
for (var i = 0; i < response.length; i++) {
this.push('certificationList', response[i].name);
}
console.log(this.certificationList);
},
_itemSelected: function(e) {
var selectedItem = e.target.selectedItem;
if (selectedItem) {
this.sendCertificationRequest(selectedItem.innerText);
console.log("selected: " + selectedItem.innerText);
}
},
_removeArray: function(arr) {
this.$.certificationList.remove();
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
arr.splice(0, i);
arr.pop();
}
console.log(arr.length);
},
_deleteElement: function() {
var element = document.getElementById('certificationSelect');
while (element.firstChild) {
element.removeChild(element.firstChild);
}
},
_createElement: function() {
var doc = document.querySelector('#test');
var option = document.createElement('option');
option.extends = "paper-item";
option.innerHTML = "Option";
doc.appendChild(option);
}
});
</script>
</dom-module>
Any guidance is always appreciated
Here's a working version of your JSBin, which uses data binding and a <template is="dom-repeat"> to create new, selectable <paper-item> elements dynamically.
I'm not sure what specific issues you ran into when using data binding to stamp out the <paper-item> elements, but the important thing to remember in Polymer 1.0 is that when you modify an Array (or an Object) that is bound to a template, you need to use the new helper methods (like this.push('arrayName', newItem)) to ensure the bindings are updated.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base href="http://element-party.xyz">
<script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="all-elements.html">
</head>
<body>
<dom-module id="x-module">
<template>
<paper-material elevation="1">
<paper-dropdown-menu>
<paper-menu class="dropdown-content" on-iron-select="_itemSelected">
<template is="dom-repeat" items="[[_menuItems]]">
<paper-item>[[item]]</paper-item>
</template>
</paper-menu>
</paper-dropdown-menu>
<paper-button on-click="_createItem">Add</paper-button>
</paper-material>
</template>
<script>
Polymer({
_createItem: function() {
this.push('_menuItems', 'New Option ' + this._menuItems.length);
},
_itemSelected: function() {
console.log('Selected!');
},
ready: function() {
this._menuItems = ['First Initial Option', 'Second Initial Option'];
}
});
</script>
</dom-module>
<x-module></x-module>
</body>
</html>

dojox/mvc/getStateful support hierarchy

Here is a dojo sandbox showing my intended use of getStateful(): http://dojo-sandbox.net/public/7917e/1
It seems that getStateful() initially creates watchCallbacks for each level of the model, but when called again in the button click getStateful() creates the watchCallbacks at the root level but not the nested level of my model.
I've looked at newStatefulModel also, but the documentation indicates that getStateful is the successor, and should be used.
If there are options I should pass to getStateful() to make this happen, how come it seemed to work initially?
EDIT: It looks like my problem is not with the getStateful method, but with the ModelRefController.set method, or more specifically the _Controller.set method.
I'm throwing a hierarchy at the ModelRefController, and it's accepting the entire hierarchy as the new "model" value, but only defining watchCallbacks on the "model" (root).
I would have expected it to accept the provided object and perform the wiring at all levels within the passed in value, instead of having to set each individual object in the hierarchy into the ModelRefController.
I may be going about it the wrong way, but I would like to have a template that knows all of the specifics about the fields it is capable of displaying, and have the widget (controller) concerned only with those properties on the model that drive logic in the widget (controller).
I'm generating the UI from a page definition, and at runtime providing additional decoration in the UI regarding the meta data of the model properties. I can easily generate the necessary calls to the ModelRefController to sync its contents with new data received from the backend, just didn't think it would require so much code.
Here's another Dojo sandbox: http://dojo-sandbox.net/public/e6946/0
The model's initial values are "Foo". And when new data is pushed into the model containing "Bar", it rebinds.
The new example in http://dojo-sandbox.net/public/ef38d/1 confirms that the application needs the "view model", which is the model the UI components looks at, to contain both of the two models to make it work.
Also, the update in the original question implies that there was an expectation for dojox/mvc/ModelRefController to support the notion of "recursive path watch", though it does not. I also have an impression that dojox/mvc/at supporting recursive path watch would the the most thing that would help http://dojo-sandbox.net/public/ef38d/1 as well as http://dojo-sandbox.net/public/e6946/0, though it's not supported. The impression is especially from http://dojo-sandbox.net/public/ef38d/1 that seems to have wanted to watch for dataModel.model.nextLevel.title path (though the code does not).
Though the implementation may not be something desirable, the best way I can think of to make the sample work is here:
<!DOCTYPE html>
<html>
<head>
<title>dojo/Stateful tree with dojox/mvc/getStateful</title>
<script type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dojo/dojo.js"
data-dojo-config="parseOnLoad: 0, async: 1, mvc: {debugBindings: 1}"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dojo/resources/dojo.css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css">
<script type="text/javascript">
require([
"dojo/_base/declare",
"dojo/Stateful",
"dojo/parser",
"dijit/Destroyable",
"dojox/mvc/getStateful",
"dojox/mvc/parserExtension",
"dojo/domReady!"
], function (declare, Stateful, parser, Destroyable, getStateful) {
var watchPath = (function () {
function getPathComps(path) {
return path === "" ? [] : typeof path.splice !== "function" ? path.split(".") : path;
}
function getObjectPath(o, path) {
for (var comps = getPathComps(path), i = 0, l = comps.length; i < l; ++i) {
var comp = comps[i];
o = o == null ? o : o[comp];
}
return o;
}
return function (model, path, callback) {
if (model && typeof model.watch === "function") {
var comps = getPathComps(path),
prop = comps.shift(),
remainder = comps,
observer = {
prop: prop,
remainder: remainder,
hProp: model.watch(prop, function (name, old, current) {
var hasRemainder = observer.remainder.length > 0;
if (old !== current) {
if (observer.hRemainder) {
observer.hRemainder.remove();
observer.hRemainder = null;
}
observer.hRemainder = watchPath(model[prop], remainder.slice(), callback);
}
callback(hasRemainder ? getObjectPath(old, observer.remainder) : old,
hasRemainder ? getObjectPath(current, observer.remainder) : current);
}),
hRemainder: watchPath(model[prop], remainder.slice(), callback),
remove: function () {
if (this.hRemainder) {
this.hRemainder.remove();
this.hRemainder = null;
}
if (this.hProp) {
this.hProp.remove();
this.hProp = null;
}
}
};
return observer;
}
};
})();
var States = declare([Stateful, Destroyable], {
constructor: function (model) {
var self = this;
}
}),
App = declare(Stateful, {
firstDisabled: false,
secondDisabled: false,
model: null,
constructor: function () {
this.switchModel();
},
createModel: function () {
var model = getStateful({
title: "Foo",
nextLevel: {
title: "Bar",
nextLevel: {
title: "Baz"
}
}
}),
states = new Stateful({
firstDisabled: model.nextLevel.title === "Foo",
secondDisabled: model.nextLevel.nextLevel.title === "Foo"
}),
h0 = watchPath(model, "nextLevel.title", function (old, current) {
states.set("firstDisabled", current === "Foo");
}),
h1 = watchPath(model, "nextLevel.nextLevel.title", function (old, current) {
states.set("secondDisabled", current === "Foo");
});
model.set("states", states);
model.nextLevel.set("states", states);
model.nextLevel.nextLevel.set("states", states);
model.destroy = function () {
if (h0) {
h0.remove();
h0 = null;
}
if (h1) {
h1.remove();
h1 = null;
}
}
return model;
},
switchModel: function () {
var oldModel = this.get("model"),
model = this.createModel();
if (oldModel) {
oldModel.destroy();
}
this.set("model", model);
}
});
window.app = new App();
parser.parse();
});
</script>
</head>
<body class="claro">
<script type="dojo/require">at: "dojox/mvc/at"</script>
<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(app, 'model')">
Selected:
<span data-mvc-bindings="innerText: at('rel:', 'title')"></span>
<select type="combo" data-dojo-type="dijit/form/Select"
data-dojo-props="value: at('rel:', 'title'), disabled: at('rel:states', 'firstDisabled')">
<option value="Foo">Foo</option>
<option value="Bar">Bar</option>
<option value="Baz">Baz</option>
</select>
<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', 'nextLevel')">
Selected:
<span data-mvc-bindings="innerText: at('rel:', 'title')"></span>
<select type="combo" data-dojo-type="dijit/form/Select"
data-dojo-props="value: at('rel:', 'title'), disabled: at('rel:states', 'secondDisabled')">
<option value="Foo">Foo</option>
<option value="Bar">Bar</option>
<option value="Baz">Baz</option>
</select>
<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', 'nextLevel')">
Selected:
<span data-mvc-bindings="innerText: at('rel:', 'title')"></span>
<select type="combo" data-dojo-type="dijit/form/Select"
data-dojo-props="value: at('rel:', 'title')">
<option value="Foo">Foo</option>
<option value="Bar">Bar</option>
<option value="Baz">Baz</option>
</select>
</div>
</div>
</div>
<div data-dojo-type="dijit/form/Button">Switch model
<script type="dojo/on" data-dojo-event="click" data-dojo-args="evt">
app.switchModel();
</script>
</div>
</body>
</html>
Hope this helps.
Best, -Akira
dojox/mvc/getStateful creates a tree of dojo/Stateful from the given object. _watchCallbacks, as the name suggests, is a private property of dojo/Stateful, which is set when one or more guys started watching for changes in its properties. Therefore _watchCalbacks not being there does not necessarily mean there is anything wrong with dojox/mvc/getStateful; Neither is it with http://dojo-sandbox.net/public/7917e/1.
What I see in http://dojo-sandbox.net/public/7917e/1 is this; As it tries to, watching for dojo/Stateful hierarchy in UI side requires dojox/mvc/Group (or something equivalent) with the right target. It needs to be done in every level of hierarchy, though. It means that if you have dojox/mvc/Group watching for model.nested, you'll see _watchCallbacks set to nested. Here's an example how to declare hierarchcal watch in UI side (focus on dojox/mvc/Group usage):
<!DOCTYPE html>
<html>
<head>
<title>dojo/Stateful tree with dojox/mvc/getStateful</title>
<script type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dojo/dojo.js"
data-dojo-config="parseOnLoad: 0, async: 1, mvc: {debugBindings: 1}"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dojo/resources/dojo.css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css">
<script type="text/javascript">
require([
"dojo/_base/declare",
"dojo/Stateful",
"dojo/parser",
"dojox/mvc/getStateful",
"dojox/mvc/parserExtension",
"dojo/domReady!"
], function (declare, Stateful, parser, getStateful) {
var App = declare(Stateful, {
model: null,
constructor: function () {
this.switchModel();
},
createModel: function () {
return getStateful({
title: "Foo",
deeper: {
title: "Bar"
}
});
},
switchModel: function () {
this.set("model", this.createModel());
}
});
window.app = new App();
parser.parse();
});
</script>
</head>
<body class="claro">
<script type="dojo/require">at: "dojox/mvc/at"</script>
<div data-dojo-type="dojox/mvc/Group"
data-dojo-props="target: at(app, 'model')">
Selected:
<span data-mvc-bindings="innerText: at('rel:', 'title')"></span>
<select type="combo" data-dojo-type="dijit/form/Select"
data-dojo-props="value: at('rel:', 'title')">
<option value="Foo">Foo</option>
<option value="Bar">Bar</option>
<option value="Baz">Baz</option>
</select>
<div data-dojo-type="dojox/mvc/Group"
data-dojo-props="target: at('rel:', 'deeper')">
Selected:
<span data-mvc-bindings="innerText: at('rel:', 'title')"></span>
<select type="combo" data-dojo-type="dijit/form/Select"
data-dojo-props="value: at('rel:', 'title')">
<option value="Foo">Foo</option>
<option value="Bar">Bar</option>
<option value="Baz">Baz</option>
</select>
</div>
</div>
<div data-dojo-type="dijit/form/Button">Switch model
<script type="dojo/on" data-dojo-event="click" data-dojo-args="evt">
app.switchModel();
</script>
</div>
</body>
</html>
Best, -Akira