2016-05-11 2 views
1

Мне нужно получить значение от объекта в генерируемом нокаутом html. Как я могу это достичь? Моя базовая структура кода выглядит следующим образом.Получение значения объекта из ключа в knockoutjs

Если есть лучший способ достичь того же, то я все уши.

В моем JS код у меня есть:

self.myObservable = ko.observable(); 
self.myObservableArray = ko.observableArray([Obj1, Obj2, Obj3]); 
self.someFunction = function() { 
    //some ajax calls which gives me an object back with a unique key 
    //so i add this to the observable. 
    self.myObservable[uniqueKey] = results; 
} 

В моем HTML у меня есть:

<div data-bind="foreach: myObservableArray"> 
    <span data-bind="name" id="clickme" data-bind="click: function(){toggle('dynamic-id-of-div')}"></span> 
    // This is where i need the value from the oject. The key is the 'name' from the Obj in the foreach 
    <div id="dynamic-id-of-div"> 
     $parent.myObservable[key].name??? 
    </div> 
</div> 
+0

Вы отметили * оба * 2.0 и 3.0. Если ваша проблема очень специфична для любого из них, я предлагаю оставить только тот. В противном случае я предлагаю удалить оба из них. – Jeroen

ответ

1

Ваш вопрос не совсем ясно (как другой ответ заявил, ...), но вот как я понял (поправьте меня, если я ошибаюсь):

  • Вы хотите сохранить один наблюдаемый объект, который хранит данные для определенных ключей.
  • Вы хотите иметь один наблюдаемый массив, в котором хранятся ключи, для которых вы хотите отображать данные.
  • Метод добавляет пары ключ/значение к первому наблюдаемому динамически.
  • Наблюдаемый массив может принимать новые ключи или удалять ключи, чтобы изменить видимость.

Вот пример реализации. Я добавил несколько комментариев, чтобы объяснить, что происходит. Дайте мне знать, если я получил ваши намерения совершенно неправильно ...

function VM() { 
 
    var self = this; 
 

 
    // I've initialized this observable with an empty object so we can add keys later 
 
    self.observableStorage = ko.observable({}); 
 
    
 
    // The data type of the items in this array wasn't clear in your question, 
 
    // I've assumed you meant 'references' to objects (string keys) 
 
    self.observableKeys = ko.observableArray(["key1", "key2", "key3"]); 
 

 
    self.getData = function() { 
 
    // This is what you would receive from the server 
 
    var mockupServerData = { 
 
     "key1": "Data For Key 1" 
 
    }; 
 

 
    // Use `()` to get the old object out of the observable 
 
    var originalStorage = self.observableStorage(); 
 
    
 
    // This creates a new object that has all the old keys, and adds the new one 
 
    var newStorage = Object.assign({}, originalStorage, mockupServerData); 
 

 
    // Setting the observable with the new object triggers an UI update 
 
    self.observableStorage(newStorage); 
 
    }; 
 
}; 
 

 
var vm = new VM(); 
 
ko.applyBindings(vm); 
 

 
vm.getData();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<ul data-bind="foreach: observableKeys"> 
 
    <li> 
 
    <strong data-bind="text: $data"></strong>: 
 
    <span data-bind="text: $parent.observableStorage()[$data] || 'No Data'"></span> 
 
    </li> 
 
</ul>

+0

Привет, действительно смущающе, но проблема в том, что я отсутствовал в скобках в своем HTML. Поэтому я называл $ parent.observableStorage [$ data] вместо $ parent.observableStorage() [$ data] !!! Спасибо за сообщение, хотя, когда я увидел ваш html, я сразу понял это – Julian

0

Помните, что если вы не используете что-то вроде knockoutjs-es5, вы всегда должны установить наблюдаемыми по телефону они как функция. Вы не можете просто использовать простое назначение, как в примере с JS-кодом, а не при автоматическом обновлении представления.

Я думаю, что вы, возможно, ищете наблюдаемый словарь, хотя ваш примерный код слишком абстрагируется, чтобы сказать. В любом случае, there is no such thing built in для KnockoutJS. Таким образом, вам необходимо либо использовать раствор из вышеупомянутой ссылке, или вам нужно переписать приложение, чтобы использовать обычный observableArray ключевых пар значений, которые будут выглядеть следующим образом:

self.myObservablePseudoDictionary = ko.observableArray([]); 
self.myObservableArray = ko.observableArray([Obj1, Obj2, Obj3]); 
self.someFunction = function() { 
    self.myObservablePseudoDictionary.push({ key: uniqueKey, value: results }); 
} 

Я не могу вам помочь с доступом к этим в вид, потому что ваш псевдокод не говорит мне, откуда приходит key. Здесь есть всевозможные варианты, и в зависимости от вашего контекста вам придется выбирать/создавать. Это осталось как упражнение для читателя :).

0
<div data-bind="foreach: myObservableArray"> 
    <div data-bind="text: name"></div> 
</div> 

Вы внутри Еогеасп, так что вы теперь на том, что объекты уровня. Вы также можете использовать $ data, то есть:

<div data-bind="text: $data.name"></div> 

Но его не нужно.

Если вы ищете, чтобы узнать, какой объект они нажали:

<div data-bind="foreach: myObservableArray"> 
    <div data-bind="click: $parent.setItem.bind($data), text: name, "></div> 
</div> 

добавить эту функцию к родителю:

self.setItem = function (item) { 
    // Do what you want with it in here. ie. self.myObservable(item); 
    self.myObservable(item); 
} 

Если вы хотите, чтобы показать пользователю, который установлен один:

<div data-bind="foreach: myObservableArray"> 
    <div data-bind="click: $parent.setItem.bind($data), text: name, css: { 'active' : ($parent.myObservable() != null && $parent.myObservable().name() == name())}"></div> 
</div> 

Это добавит активный класс к выбранным элементам div.

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