2013-06-01 3 views
5

Я пытаюсь собрать демо, чтобы использовать knockout-es5 plugin для упрощения моделей, использующих раскрывающий шаблон модуля. ViewModel1 - оригинальная модель нокаута, и она отлично работает. ViewModel2 - это попытка использовать плагин knockout-es5. Работа в нескольких вещахВыявление шаблона модуля с помощью Knockout-es5

  • Вычисляемые свойства не работают, поскольку локальные переменные не отслеживаются (например, fullName1). Я могу использовать ko.defineProperty, но сначала он отделен от других свойств, второй должен использовать this.propertyName.
  • Изменения, внесенные функциями-членами, не отражаются, вероятно, по той же причине (например, doSomething). Снова использование this.propertyName работает, но шаблон RM нарушается.

JS Fiddle

var NS = NS || {}; 

$(function() { 

    NS.ViewModel1 = function (first, last) { 
     var 
      firstName = ko.observable(first), 
      lastName = ko.observable(last), 
      fullName = ko.computed(function() { 
       return firstName() + " " + lastName(); 
      }), 
      doSomething = function (n) { 
       lastName(lastName() + " " + n); 
      } 
     ; 

     return { 
      firstName: firstName, 
      lastName: lastName, 
      fullName: fullName, 
      doSomething: doSomething 
     }; 
    }; 

    NS.ViewModel2 = function (first, last) { 
     var 
      firstName = first, 
      lastName = last, 
      fullName1 = ko.computed(function() { 
       // Changed values are not reflected 
       return firstName + " " + lastName; 
      }), 
      fullName2 = ko.computed(function() { 
       // Should not work 
       return this.firstName + " " + this.lastName; 
      }), 
      doSomething = function (n) { 
       // Doesn't work 
       lastName += " " + n; 
       // Works 
       // this.lastName += " " + n; 
      } 
     ; 

     var retObj = { 
      firstName: firstName, 
      lastName: lastName, 
      fullName1: fullName1, 
      fullName2: fullName2, 
      doSomething: doSomething 
     }; 

     ko.track(retObj); 
     ko.defineProperty(retObj, 'fullName3', function() { 
      // Changed values are not reflected 
      return firstName + " " + lastName; 
     }); 
     ko.defineProperty(retObj, 'fullName4', function() { 
      // Works 
      return this.firstName + " " + this.lastName; 
     }); 

     return retObj; 
    }; 

    var vm1 = new NS.ViewModel1("John", "Doe"); 
    ko.applyBindings(vm1, document.getElementById("observableSection")); 

    var vm2 = new NS.ViewModel2("Jane", "Doe"); 
    ko.applyBindings(vm2, document.getElementById("withoutObservableSection")); 

    setTimeout(function() { 
     vm1.firstName("John 1"); 
     vm2.firstName = "Jane 1"; 
    }, 2000); 

    setTimeout(function() { 
     vm1.doSomething(2); 
     vm2.doSomething(2); 
    }, 4000); 
}); 

ответ

1

Я не уверен, каков ваш вопрос, но да, он не будет работать с шаблоном, который вы пытаетесь использовать.

Мне нравится идея нокаута-es5, но в текущем API, который он предоставляет, есть некоторые проблемы, которые могут действительно вызвать у вас проблемы, если вы отклонились от их шаблона.

Еще одна проблема заключается в том, что если вы передадите this.property в какую-либо другую схему просмотра, целью которой является то, что другая модель может быть подписана на наблюдаемую или обновлять наблюдаемую, то она явно не сработает. Вы просто передадите текущее значение. Вы должны помнить, что в этой ситуации вы можете наблюдать за своей собственностью. Используя добрый старый нокаут, вы знаете, что проходите мимо наблюдаемого, когда получаете доступ к собственности.

Проект молод, поэтому, надеюсь, эти проблемы API будут решены. Но прямо сейчас, это требует, чтобы разработчик помнил слишком много вещей, чтобы понять это правильно.

+0

Спасибо за ответ. Проект уже использует этот шаблон, поэтому я надеялся использовать новый плагин для упрощения продвижения моделей. Чем больше я занимаюсь этим, тем больше я понимаю, что плагин предназначен для использования с тем, как модели определены в вышеупомянутом блоге и многих других примерах. Это нормально, я просто хотел убедиться, что я не пропустил ничего очевидного. Иногда ответ «Это невозможно сделать так» - правильный ответ. Я оставлю его открытым на пару дней и приму это. –

2

Это не сработало, потому что вы связаны JS непосредственно с GitHub. См. Обновленную скрипту, которая работает: http://jsfiddle.net/tkirda/Wznkm/1/

Причина, по которой это не работает, объясняется тем, что Github указывает, что тип содержимого является «текстовым/простым», а не «application/x-javascript».

Content-Type:text/plain; charset=utf-8 
Access-Control-Allow-Origin:https://render.github.com 

Поэтому браузеры не выполняют этот код. Думаю, они сделали это так, чтобы люди перестали связывать файлы с GitHub.

UPDATE: В вашем случае lastName изменилось, добавьте console.log, и вы увидите его новое значение.

 doSomething = function (n) { 
      // Doesn't work 
      lastName += " " + n; 
      console.log(lastName); 
      // Works 
      // this.lastName += " " + n; 
     } 

Однако он не используется моделью, потому что, когда вы назначили им retObj, вы передали только значения, а не ссылку. Потому что строка - это тип значения. Когда вы работаете с функциями, они имеют ссылочный тип. Таким образом, вы просто обновили локальную переменную, но ваша модель не привязана к этой переменной.

var retObj = { 
      firstName: firstName, 
      lastName: lastName, 
      fullName1: fullName1, 
      fullName2: fullName2, 
      doSomething: doSomething 
     };         

Надеюсь, это имеет смысл.

+0

Обе скрипки работают exac то же самое, по крайней мере, для меня. Проблема заключается в двух методах определения моделей. Наблюдаемое сечение работает так, как ожидалось, в то время как withoutObservableSection этого не делает. Обе части должны отображать «John 1 Doe 2» после обоих тайм-аутов. У меня также есть тот же код локально, где обе лобы обслуживаются локально, и я получаю такое же поведение. –

+0

Отметьте обновленный ответ. –

+0

Спасибо за обновление. Я понимаю, почему он не работает. Есть ли способ обойти это или я могу не использовать эти два вместе, то есть использовать другой шаблон или продолжать использовать традиционный синтаксис для свойств. –

1

Столько, сколько я ненавижу с использованием функций конструктора и сломанный «это» ключевое слово, выявление шаблон модуля почти полностью несовместима с плагином ES5 кё (Вы можете заставить его работать в очень запутанной и хрупкой, как и только в простых сценариях)

отслеживаемый свойство нуждается в хост-объект (так в отличие от частной Пере) и не может быть скопирован (как вы затем потерять вновь сгенерированный геттер)

так выбрать меньшее из двух зол: p (для меня это синтаксис ES5)

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