El Observable protegido vuelve a renderizar todo el modelo de vista

I have an issue using the protectedObservable custom binding below found at this link.


The protected observable is nested within 3 child templates.

<select class="select-teams bracket-select" data-bind="value: divisionTeamId, options: $root.teams, optionsText: 'Name', optionsValue: 'Id', optionsCaption: ' - Teams - '"></select>

When this isn't a protected observable the viewmodel doesn't rerender itself. When it is protected the template rerenders and it loses it's initial value. Any clue why this is going on?

self.divisionTeamId = ko.protectedObservable(undefined);

Encuadernación personalizada

ko.protectedObservable = function (initialValue) {

        var _actualValue = ko.observable(initialValue),
        _tempValue = initialValue;

        var result = ko.computed({
            read: function () {
                return _actualValue();
            write: function (newValue) {
                _tempValue = newValue;

        result.commit = function () {
            if (_tempValue !== _actualValue()) {

        result.reset = function () {
            _tempValue = _actualValue();

        return result;

enter image description here


I found that removing the stopBinding fixed the issue.

<div data-bind="stopBinding: true">
    <div id="bracket-namespace">

    app.members.bracket.init = function (options) {
        viewModel = new ViewModel(options);

        ko.applyBindings(viewModel, document.getElementById("bracket-namespace"));

ko.bindingHandlers.stopBinding = {
    init: function () {
        return { controlsDescendantBindings: true };

preguntado el 24 de agosto de 12 a las 06:08

Can you put something in jsFiddle? Maybe a simplified sample. There are a number of ways to tweak the protected observable, if necessary. -

Also, you will always want to put the value vinculante después de la options binding in a select. If the options are not already present, then the value binding will believe that your choice is invalid. -

I will try to create a Fiddle but the page contains alot of logic and html so Im not sure I can replicate it unless I replicate the whole page. I tried to put the value at the end of the binding, but same deal. -

I just couldn't replicate this in JFiddle. I attached a screenshot of the callstack. When I hit reset it calls valueHasMutated on the actual value, but then goes down the line and calls html.update which is dynamic HTML. This shouldn't be reevaluated and re-rendered. -

Looks like I found the issue from the Update above. Any clue why this would happen? -

1 Respuestas

I removed the stopBinding:true and it fixed it. So I took a different route with populating the dynamic HTML since I still wanted to use stopBinding:true. I explicitly populated the dynamic HTML container that is filled during an ajax call. So instead of setting it with the "html" binding of the container element, I used jQuery $(container).html(...) to populate it. My final implementation is below. The stopBinding either uses the parent VM or a new one depending on the ajax page stopBinding property.

<div id="container" class="clearfix" data-bind="stopBinding: members.stopBinding, container: {}">  

Respondido 27 ago 12, 18:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.