问题描述:

I'm having an issue getting Knockout binding handlers working with Durandal. I currently have a file named bindings.js that I'm loading into a viewmodel named todo.js via RequireJS. And for some reason, the binding handlers just don't seem to be attaching. Enter key doesn't work after adding a todo and hitting return on the keyboard. Any help appreciated. The code for the project is at https://github.com/robksawyer/durandal-todo. Feel free to fork it. It's also worth noting that most of the Knockout code came from the TodoMVC Knockout+Require project.

Below is a snippet of the bindings.js file. File located at https://github.com/robksawyer/durandal-todo/blob/master/scripts/bindings.js.

// a custom binding to handle the enter key (could go in a separate library)

ko.bindingHandlers.enterKey = {

init: function (element, valueAccessor, allBindingsAccessor, data) {

var wrappedHandler, newValueAccessor;

system.log("ENTER KEY PRESSED");

// wrap the handler with a check for the enter key

wrappedHandler = function (data, event) {

if (event.keyCode === config.ENTER_KEY) {

valueAccessor().call(this, data, event);

}

};

// create a valueAccessor with the options that we would want to pass to the event binding

newValueAccessor = function () {

return {

keyup: wrappedHandler

};

};

// call the real event binding's init function

ko.bindingHandlers.event.init(element, newValueAccessor, allBindingsAccessor, data);

}

};

Here is a snippet from the HTML that is connecting the bindingHandler. File at https://github.com/robksawyer/durandal-todo/blob/master/views/todos.html.

<header id="header">

<h1>todos</h1>

<input id="new-todo" type="text" data-bind="value: current, valueUpdate: 'afterkeydown', enterKey: add" placeholder="What needs to be done?" autofocus>

</header>

And finally, here's a snippet from the viewmodel where it's loaded. File located at https://github.com/robksawyer/durandal-todo/blob/master/viewmodels/todos.js.

define(

[

'knockout',

'jquery',

'durandal/app',

'durandal/system',

'scripts/dataservice',

'scripts/model',

'scripts/config',

'scripts/bindings',

'scripts/native'

],

function(ko, $, app, system, dataservice, model, config) {

'use strict';

var self = this;

var todos = ko.observableArray([]),

current = ko.observable(), // store the new todo value being entered

showMode = ko.observable('all');

// add a new todo, when enter key is pressed

var add = function() {

var current = current().trim();

if (current) {

todos.push(new model.Todo(current));

current('');

}

};

...

Thanks again for your time.

网友答案:

Binding.js is not in AMD format, so I'd suggest loading it after you load knockout and not declare it as dependency. Is scripts/native in AMD format?

define(
    [
    //'knockout', // Durandal expects knockout and $ loaded via script tag,
    //'jquery',   // no need to define them as deps as well
    'durandal/app', 
    'durandal/system', 
    'scripts/dataservice', 
    'scripts/model',
    'scripts/config',
     //'scripts/bindings',
    'scripts/native' // remove if not in AMD format
    ], 
    function(app, system, dataservice, model, config) {
    'use strict';
相关阅读:
Top