2012-02-22 3 views
6

Я привязки данных к странице с помощью KnockoutJS, модели представления заселяется посредством ответа JSON из вызова AJAX с помощью mapping plugin, например:KnockoutJS - Добавление вычисленных значений наблюдаемой массив

$(function() { 
    $.getJSON("@Url.Action("Get")", 
     function(allData) { 
      viewModel = ko.mapping.fromJS(allData); 

      viewModel.Brokers.Url = ko.computed(function() 
      { 
       return 'BASEURLHERE/' + this.BrokerNum(); 
      }); 

      ko.applyBindings(viewModel); 
    }); 
}); 

Средняя часть там не работает (она отлично работает без этого вычислимого свойства). «Брокеры» - это наблюдаемый массив, и я хочу добавить вычисленное значение для каждого элемента массива, называемого URL. Я привязываю массив Brokers к foreach, и я бы хотел использовать этот URL как атрибут href якоря. Есть идеи?

ответ

12

Ну, если вы хотите Url каждого брокера, вы должны добавить его к каждому брокеру:

$.each(viewModel.Brokers(), function(index, broker){ 
    broker.Url = ko.computed(function(){return 'BASEURLHERE/' + broker.BrokerNum();}); 
}); 

Я думаю BrokerNum не изменится, так что вы можете также просто вычислить Url сразу:

$.each(viewModel.Brokers(), function(index, broker){ 
    broker.Url = 'BASEURLHERE/' + broker.BrokerNum(); 
}); 

Вы также можете добавить свойство Url во время сопоставления, предоставив «create» callback функции ko.mapping.fromJS. См. mapping plugin docs.

Если вам нужно только URL, чтобы привязать к HREF, просто связать выражение в HTML (в пределах Еогеасп связывания):

<a data-bind="attr: {href: 'BASEURLHERE/' + BrokerNum()}">link to broker details</a> 
11

я работаю через очень похожие вопросы, и я обнаружил, что вы можете перехватывать создание объектов Брокерские и вставить свои собственные поля с помощью параметра параметров картографирования:

var data = { "Brokers":[{"BrokerNum": "2"},{"BrokerNum": "10"}] }; 

var mappingOptions = { 
    'Brokers': { 
     create: function(options) { 
      return (new (function() { 
       this.Url = ko.computed(function() { 
        return 'http://BASEURLHERE/' + this.BrokerNum(); 
       }, this); 

       ko.mapping.fromJS(options.data, {}, this); // continue the std mapping 
      })()); 
     } 
    } 
}; 

viewModel = ko.mapping.fromJS(data, mappingOptions); 

ko.applyBindings(viewModel); 

Здесь скрипку, чтобы продемонстрировать это: http://jsfiddle.net/pwiles/ZP2pg/

+0

Этот подход работает как шарм! – Tobscher

0

Благодаря Петру Уайлс я очень похожее решение:

var ViewModel = function (data, ranges) { 
    var self = this; 

    this.productList = ko.observableArray(); 
    var productListMapping = { 
     create: function (options) { 
      return (new (function() { 
      //this row above i don't understand... 
       this.len = ko.computed(function() { 
        //just test function returning lenght of object name 
        // and one property of this model 
        return this.name().length + ' ' + self.cons_slider_1(); 
       }, this); 

       ko.mapping.fromJS(options.data, {}, this); // continue the std mapping 
      })()); 
     } 
    } 

    this.cons_slider_1 = ko.observable(100); 

    ko.mapping.fromJS(data, productListMapping, this.productList); 
}; 

Некоторые различия: Я не отображение на себя, а на this.product. Вход JSON не имеет родительское имя, как «ПОВ» в приведенном выше примере:

var products = [ 
    { "id": "pp1", "name": "Blue windy" }, 
    { "id": "pp1", "name": "Blue windy" }]; 

Так в productMapping я печатаю просто «создать:»

Но то, что я не понимаю, структура создать функцию. Может ли кто-нибудь объяснить мне, почему функция возвращает новую функцию, которая имеет свойство. Разве это не могло быть упрощено?

 Смежные вопросы

  • Нет связанных вопросов^_^