Как динамически установить начальное значение для компонента MVC Vanilla Javascript? - PullRequest
0 голосов
/ 28 марта 2019

Я пробую подход MVC к использованию ванильных компонентов JS.

Однако при следующей настройке я не могу обновить вид в зависимости от модели.

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

Я понимаю значение. Однако шаблон HTML не обновляется.

Теперь в следующем примере кода показано много стандартного кода. Это необходимо, чтобы получить функционально работающий пример. Болевая точка, кажется, в основном в классе TestView.

// unrelated helper function
const stringToHTMLCollection = function(string) {
  const template = document.createElement('template');
  string = string.trim(); // Never return a text node of whitespace as the result
  template.innerHTML = string;
  return template.content.children;
}

class TestModel {
	constructor(data) {
  	this._firstValue = data.first;
  }
  get firstValue() {
  	return this._firstValue;
  }
}

class TestController {
	constructor(model) {
  	this.model = model;
  }
  get firstValue() {
  	return this.model.firstValue;
  }
}


class TestView {

	static htmlString() {
  	return `<div>
      	<ul>
	        <li id="first-list-item">0</li>
          <li>0</li>
        </ul>
      </div>`
  }

	constructor(controller) {
  	this.controller = controller;
  	this.testView = TestView.htmlString();
    this.list = stringToHTMLCollection(this.testView)[0];
    this.listItems = this.list.getElementsByTagName('li');
    this.init();
  }
  
  init() {
    // this is going well, output: 100
  	console.log(this.controller.firstValue);
     
    Object.entries(this.listItems).forEach(([key, price]) => {
      if (price.id === 'first-list-item') {
        price.innerHTML = this.controller.firstValue;
      }
    });

    // this is going well, output element with innerText of 100
    console.log(this.listItems[0]);
  }
  
  renderInto(targetNode) {
  	if(!targetNode) return;
    targetNode.insertAdjacentHTML('beforeend', this.testView);
  }
}

const resultElement = document.getElementById('result');

function testComponent(pricing) {
	const testModel = new TestModel(pricing),
   	    testController = new TestController(testModel);
	return new TestView(testController);
}

const pricing = {
	first: 100,
  second: 200
}

testComponent(pricing).renderInto(result);
<div id="result"></div>

1 Ответ

0 голосов
/ 28 марта 2019

Ах, я думаю, что stringToHTMLCollection фактически создает новый экземпляр. Используя его как определение в конструкторе, а затем возвращая его после того, как init решит его.

Пример:

// unrelated helper function
const stringToHTMLCollection = function(string) {
  const template = document.createElement('template');
  string = string.trim(); // Never return a text node of whitespace as the result
  template.innerHTML = string;
  return template.content.children;
}

class TestModel {
	constructor(data) {
  	this._firstValue = data.first;
  }
  get firstValue() {
  	return this._firstValue;
  }
}

class TestController {
	constructor(model) {
  	this.model = model;
  }
  get firstValue() {
  	return this.model.firstValue;
  }
}


class TestView {

	static htmlString() {
  	return `<div>
      	<ul>
	        <li id="first-list-item">0</li>
          <li>0</li>
        </ul>
      </div>`
  }

	constructor(controller) {
  	this.controller = controller;
  	this.testView = TestView.htmlString();
    this.html = stringToHTMLCollection(this.testView);
    this.list = this.html[0];
    this.listItems = this.list.getElementsByTagName('li');
    this.init();
  }
  
  init() {
    // this is going well, output: 100
  	console.log(this.controller.firstValue);
     
    Object.entries(this.listItems).forEach(([key, price]) => {
      if (price.id === 'first-list-item') {
        price.innerHTML = this.controller.firstValue;
      }
    });

    // this is going well, output element with innerText of 100
    console.log(this.listItems[0]);
  }
  
  renderInto(targetNode) {
  	if(!targetNode) return;
    targetNode.insertAdjacentElement('beforeend', this.html[0]);
  }
}

const resultElement = document.getElementById('result');

function testComponent(pricing) {
	const testModel = new TestModel(pricing),
   	    testController = new TestController(testModel);
	return new TestView(testController);
}

const pricing = {
	first: 100,
  second: 200
}

testComponent(pricing).renderInto(result);
<div id="result"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...