KnockoutJS ловит ошибки Binding

Я хочу поймать ошибку, исправить ее и продолжить выполнение программы.http://jsfiddle.net/Gthv9/12/

Но я не могу этого сделать!

Если вы нажмете: «повторно проверить модель 1», «повторно проверить модель 3» - все в порядке.

Если вы нажмете: «повторно проверить модель 1», «повторно проверить модель 2», «повторно проверить модель 3» - возникнет ошибка.

Uncaught Error: Unable to parse bindings.
Message: ReferenceError: name3 is not defined;
Bindings value: text: name3 

Почему?

Я поместил код проблемы в блок try-catch (viewModel.recheckData2 ()), но приложение вылетает при нажатии viewModel.recheckData3 ()!

Я знаю, что knockoutJS хранит состояние ошибки (new model2 ()), но не знаю, что мне делать.

Как правильно отловить ошибку?

Спасибо!

Ответы на вопрос(2)

Решение Вопроса

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

Если ваша проблема - просто неопределенные переменные, то вы можете использовать один трюк$data.name3 а не простоname3, Доступ к неопределенному свойству допустимого объекта не вызывает ошибку.

Если вы действительно хотите что-то более надежное, то вы можете использоватьпользовательский поставщик привязки.

Например, вы можете написать быструю оболочку для реального поставщика привязок, например:

var ErrorHandlingBindingProvider = function() {
    var original = new ko.bindingProvider(); 

    //determine if an element has any bindings
    this.nodeHasBindings = original.nodeHasBindings;

    //return the bindings given a node and the bindingContext
    this.getBindings = function(node, bindingContext) {
        var result;
        try {
            result = original.getBindings(node, bindingContext);
        }
        catch (e) {
            if (console && console.log) {
                console.log("Error in binding: " + e.message);   
            }
        }

        return result;
    };
};

ko.bindingProvider.instance = new ErrorHandlingBindingProvider();

Это будет ловить ошибки, регистрировать их и продолжать. Конечно, элемент, имеющий эту «плохую» привязку, не будет связан. Если есть какой-то известный способ обработки, вы можете добавить эту логику после обнаружения ошибки. Может быть, вы хотите проверить этот элемент (узел) и bindingContext, чтобы определить, что нужно сделать.

Образец:http://jsfiddle.net/rniemeyer/KxXqs/

ОБНОВЛЕНИЕ: это версия для 3.0+, которая перехватывает / регистрирует ошибки в синтаксисе привязки, а также ошибки, когда фактически оценивается связанное значение.http://jsfiddle.net/rniemeyer/ecbn1dmy/

 zoh02 нояб. 2012 г., 06:44
Вы нокаут гуру! :)
 RP Niemeyer29 окт. 2014 г., 22:42
@ShaunRowan - интерфейс связывания слегка изменился в 3.0 для использованияgetBindingAccessors, несмотря на то чтоgetBindings все еще поддерживается, у этого может быть тот тип побочного эффекта в зависимости от выполнения кода. Вот версия, которая работает с 3.0+, которая перехватывает как синтаксические ошибки, так и ошибки в фактическом значении привязки при его оценке:jsfiddle.net/rniemeyer/ecbn1dmy
 Shaun Rowan29 окт. 2014 г., 21:45
По какой-то причине я не смог определить, у этого подхода есть непреднамеренные побочные эффекты в нокауте 3.2: он заставляет все привязки оцениваться дважды (что может иметь огромные последствия для производительности и поведения).jsfiddle.net/38qowkey
 RP Niemeyer02 мар. 2013 г., 04:01
@DavidHyogo - у вас есть jsFiddle или пример кода? Похоже, что-то еще происходит.
 DavidHyogo02 мар. 2013 г., 03:56
@RP Niemeyer «Доступ к неопределенному свойству из допустимого объекта не вызывает ошибку» - я назначил функцию свойству name привязки шаблона. Если функция возвращает undefined, я получаю некатируемую ошибку, о которой спрашивает спрашивающий, использую ли я $ root или $ data или просто имя функции. Будет использоватьcomputed помочь в этом случае?

чтобы утешить узел, вызывающий ошибку в блоке catch, - это действительно облегчает поиск ошибки на сложной странице:

if (console && console.log) {
            console.log("Error in binding: " + e.message);
            console.log("Node causing error:");
            console.log(node);
        }

Ваш ответ на вопрос