knockout.observableDictionary icon indicating copy to clipboard operation
knockout.observableDictionary copied to clipboard

Does not update the UI when changed

Open scottgal opened this issue 11 years ago • 9 comments

Simple code

function getPageContent(localeKey, pageKey, varToPopulate) {
    var contentRequest = {
        LocaleKey: localeKey,
        PageKey: pageKey
    };


    $.getJSON('api/pagecontent', contentRequest, function (data) {
        varToPopulate.pushAll(data.ContentElements);

When I change the locale key I need it to repopulate and have the UI update too. However I don't know how to get that to work (oh, and 'subscribe' would be lovely!)

scottgal avatar Apr 17 '13 07:04 scottgal

Scott, does something like the following help? http://jsfiddle.net/joshka/dP5BV/#base

joshka avatar Apr 17 '13 09:04 joshka

Nope, this is using Durandal so I cannot apply bindings manually. What DID help was just changing the code to add each item one at a time, e.g.: return $.getJSON('api/pagecontent', contentRequest, function (data) { $.each(data.ContentElements, function (key, value) { varToPopulate.push(key, value); });

Which DOES suggest there's something different happening...betweeen pushAll and push.

scottgal avatar Apr 17 '13 09:04 scottgal

Can you provide a simple repro?

joshka avatar Apr 17 '13 09:04 joshka

Ok, this seems to work in my situation (I replace existing items with new ones with the same key)

pushAll: function (dictionary) { var self = this; var outArr = new Array(); if (dictionary instanceof Array) { $.each(dictionary, function (index, item) { var key = self._keySelector(item, index); var value = self._valueSelector(item); outArr.push(new DictionaryItem(key, value, self));

            });
        }
        else {
            for (var prop in dictionary) {
                if (dictionary.hasOwnProperty(prop)) {
                    var item = dictionary[prop];
                    var key = self._keySelector(item, prop);
                    var value = self._valueSelector(item);
                    outArr.push(new DictionaryItem(key, value, self));

} } } self.items.valueWillMutate(); self.items( outArr); self.items.valueHasMutated(); }

scottgal avatar Apr 17 '13 10:04 scottgal

Hi Scott.

Apologies. I need to fix my mail settings. It was going into a cc folder I hardly ever check. If only github sent mail "To" me!

I didn't really think anyone would ever use this. It was very experimental. :)

Yeah pushAll was an attempt to do many updates with only one notification (i.e. not triggering UI updates during a batch operation). but it seems to be removing old elements where there are duplicate keys (breaking the reference bound to the UI) instead of updating existing elements. I'll have a look at fixing that tonight.

How are you finding it? useful?

jamesfoster avatar Apr 30 '13 12:04 jamesfoster

Hi, yup, very useful, currently using it in a site which has dynamic content. As I say the method I used to fix it works for me but others may find it doesn't do what they expect...(as they probably expect it to add new keys whilst updating old ones). Scott

On 30 April 2013 13:25, James Foster [email protected] wrote:

Hi Scott.

Apologies. I need to fix my mail settings. It was going into a cc folder I hardly ever check. If only github sent mail "To" me!

I didn't really think anyone would ever use this. It was very experimental. :)

Yeah pushAll was an attempt to do many updates with only one notification (i.e. not triggering UI updates during a batch operation. but it seems to removing old elements where there are duplicate keys (breaking the reference bound to the UI) instead of updating existing elements. I'll have a look at fixing that tonight.

How are you finding it? useful?

— Reply to this email directly or view it on GitHubhttps://github.com/jamesfoster/knockout.observableDictionary/issues/4#issuecomment-17223919 .

scottgal avatar Apr 30 '13 12:04 scottgal

another trick is

<div data-bind="with: dictionary.items">
  ....
  <div data-bind="text: $parent.dictionary.get('key')"></div>
  ....
</div>

That way the content get refreshed whenever the items array changes, but that's a bit hacky.

jamesfoster avatar Apr 30 '13 12:04 jamesfoster

I have a dictionary of arrays and I'm trying to nest the bindings. I tried a few different ways, the best I got was the initial binding, but no update if these arrays elements changed. Any pointers?

ivanhoe1982 avatar Jul 08 '13 22:07 ivanhoe1982

Storing observable arrays in the dictionary should be fine. Could you provide a code snippet which shows the problem?

On 8 Jul 2013, at 23:59, ivanhoe1982 [email protected] wrote:

I have a dictionary of arrays and I'm trying to nest the bindings. I tried a few different ways, the best I got was the initial binding, but no update if these arrays elements changed. Any pointers?

— Reply to this email directly or view it on GitHub.

jamesfoster avatar Jul 09 '13 00:07 jamesfoster