问题
I'm developing a website using Durandal/Knockout/Breeze/WebApi with MVC4 as the back end. I'm querying my api via breeze like so:
var getCategories = function() {
var query =
entityQuery
.from('Categories')
.orderBy('Order');
return manager.executeQuery(query);
};
Then, on my view model:
function initCategories() {
service.getCategories()
.then(querySuccess)
.fail(queryFail);
function querySuccess(data) {
vm.categories(data.results);
};
where vm is my bounded view model and categories is of observableArray of course.
Finally, my view has:
<!-- ko foreach: categories -->
<div class="list_images">
<a data-bind="attr: { href: '#search/' + queryString() }" class="hover-shadow">
<img data-bind="attr: { src: image(), alt: name() }" width="240" height="180">
<h5 data-bind="text: name()"></h5>
</a>
</div>
<!-- /ko -->
Here's the screenshot of what data.results contains:
It works fine, except for the need of using the parentheses. With 'normal' viewmodels I don't need parentheses in the view bindings. I can't figure out why it happens only with breeze objects (Entities).
Edit After further investigation I noticed that my entities are of type proto._setCtor.proto instead of just an Object. Why's that? Even if I use the breeze manager to create a new entity - this is the object I get back :( What's wrong here?
回答1:
This isn't an answer. This is a confession that I'm mystified. I can't duplicate the problem you describe.
I understand exactly what you are asking. I agree that you should not have to use the parentheses. You should be able to write:
<h5 data-bind="text: name"></h5>
and not have to write:
<h5 data-bind="text: name()"></h5>
I downloaded the "Todo-Knockout" sample from Breeze. After confirming that it worked, I started changing it to look more like your binding example. I continued to work.
You can follow along with me, step-by-step, confirming that everything works as expected after each step.
Switched to the comment form of repeater:
<!-- ko foreach: items -->
Replaced the
<ul>
and<li>
tags withdiv
container.Switched to the debug version of KO (that's what you're using)
Updated to the latest KO (knockout-3.1.0.debug.js)
In the end, my revised markup looks like this:
<!-- ko foreach: items -->
<div>
<div data-bind="visible: !isEditing()">
<input type="checkbox" data-bind="checked: IsDone" />
<label data-bind="text: Description, click: $parent.editBegin, css: { done: IsDone, archived: IsArchived }"></label>
<a href="#" data-bind="click: $parent.deleteItem">X</a>
</div>
<div data-bind="visible: isEditing">
<form data-bind="event: { submit: $parent.editEnd }">
<input type="text" data-bind="value: Description, hasfocus: isEditing" />
</form>
</div>
</div>
<!-- /ko -->
When I break in the Chrome Developer Tools where the results are returned from the server and display data.results
in the console, I get this:
[proto._setCtor.proto
CreatedAt: function dependentObservable() {
Description: function dependentObservable() {
Id: function dependentObservable() {
IsArchived: function dependentObservable() {
IsDone: function dependentObservable() {
entityAspect: ctor
isEditing: function observable() {
__proto__: Object
, proto._setCtor.proto, proto._setCtor.proto]
I'm not seeing any significant differences from your example. Do you?
What happens when you do the same thing with the same "Todo-Knockout" sample on your machine?
What browser are you using? Do you see the same misbehavior in Chrome?
回答2:
Breeze serializes all of the properties of your entity into ko.computeds under the covers. It uses this to intercept changes to the properties and notify all the other places your property is used. That being said you should only have to use parans in places where you are using conditional bindings (such as when you are combining a property with some string to make a longer string. Where ever you are just binding to a standard ko binding handler you should not need it.
来源:https://stackoverflow.com/questions/23447890/why-is-my-ko-bindings-need-parentheses