2016-01-19 7 views
1

Я уверен, что у меня отсутствует что-то совершенно очевидное здесь, но я впервые пробовал ES6, и через пять дней после того, как я стал нигде, я решил, что откройте это сообщество.Компонент нокаута не привязывающий вид модели (ES6)

У меня есть вид модели класс:

class TestViewModel 
{ 
    constructor(params) 
    { 
    this.firstName = ko.observable(params.firstName); 
    this.message = ko.computed(function() { return 'Hello, ' +  this.firstName() + '!' }, this); 
    } 
} 

export default { viewModel: TestViewModel, template: templateMarkup }; 

(Ignore шаблон, это просто тэг абзаца, используя импорт)

Тогда есть точка входа:

"use strict"; 
import $ from 'jquery'; 
import ko from 'knockout'; 
import comp from '../test-model/test-model'; 

ko.components.register("test-model", { 
    viewModel: comp.viewModel, 
    template: comp.template 
}); 

let m = new comp.viewModel({ firstName: "world" }); 

$("document").ready(function() { 
    ko.applyBindings(m); 
}); 

Мои страница имеет простой компонент:

<test-component></test-component> 

Когда я просматриваю страницу, элемент содержит шаблон моего компонента. Вместо отображения сообщения «Hello, world!» На странице отображается «Hello, undefined!». Я несколько раз отлаживал этот процесс и всегда успешно создавал экземпляр TestViewModel с соответствующими параметрами. Но модель представления, которая привязана к странице, генерируется после этого функцией createViewModel в Knockout. Что мне не хватает в моей настройке, чтобы привязать мой экземпляр модели к компоненту?

ответ

1

Вы смешиваете компоненты и модель корневого представления. Ваш конструктор будет вызываться дважды:

  1. После того, потому что вы new это самостоятельно на let m... линии;
  2. Однажды, потому что ваш объект создает экземпляр компонента, говоря KO, чтобы создать экземпляр вашего viewModel;

Вместо этого вам нужно что-то вроде этого:

"use strict"; 
 

 
class TestViewModel 
 
{ 
 
    constructor(params) 
 
    { 
 
    this.firstName = ko.observable(params.firstName); 
 
    this.message = ko.computed(() => 'Hello, ' + this.firstName() + '!'); 
 
    } 
 
} 
 

 
var templateMarkup = "<p data-bind='text: message'></p>"; 
 
var comp = { viewModel: TestViewModel, template: templateMarkup }; 
 

 
ko.components.register("test-component", { 
 
    viewModel: comp.viewModel, 
 
    template: comp.template 
 
}); 
 

 
$("document").ready(function() { 
 
    ko.applyBindings({}); 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<test-component params="firstName: 'world'"></test-component>

Это seems to work, но я все же рекомендую быть осторожным с этим. Запись ko.components 'viewModel называется функцией-конструктором, и я лично не знаю тонких различий между конструкторской функцией и классом ES6. Основано на the docs. Вы можете играть в нее безопасно и вместо этого использовать нестандартную модель:

ko.components.register("test-component", { 
    viewModel: { createViewModel: (params, componentInfo) => new comp.viewModel(params) }, 
    template: comp.template 
}); 
+0

Спасибо за пример и пояснения. Теперь это имеет гораздо больший смысл. Что касается классов ES6, я использую Babel для преобразования их в ES5, поэтому они просто становятся функциями. – mgw854

+0

Ах, я не знал, что ты использовал Вавилон, но с контрольной отметки я понял, что предлагаемое решение все равно получило трюк :-). Счастливое кодирование! – Jeroen

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

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