简体   繁体   中英

KnockoutJS - bind properties ob object in observable array

function OutletsView(){
  self = this;
  self.locations = ko.observableArray(<?php echo json_encode($locations); ?>);
}

ko.applyBindings(new OutletsView());

Locations come in structure

[
{
  name: 'Demo',
  oid: 1,
  children: [
    {
      id: 2,
      name: 'de'
    },
    {
      id: 2,
      name: 'de'
    }
  ]
},
{
  name: 'Demo',
  oid: 1,
  children: [
    {
      id: 2,
      name: 'de'
    },
    {
      id: 2,
      name: 'de'
    }
  ]
}
]

I need to bind oid and to change in a html

<script type="text/html" id="location-filter">
    <div>
        <div data-bind="text: oid"></div>
        <div>
            <ul data-bind="foreach: locations">
                <li data-bind="text: name, click: $parent.applyFilter(id, name, $parent)"></li>
            </ul>
        </div>
    </div>
</script>

So i want to change oid but can't find how Can anyone help me ?

Edit:

function OutletsView(){
        self.locations = ko.observableArray([]);
        self.getChildLocations = function(id){
            $.post('<?=$this->url(array('controller' => 'location', 'action' => 'get-locations'), 'default', true); ?>',
                {id: id},
                function(data){
                    var parsed = $.parseJSON(data);
                    var item = new Location(parsed);
                    self.locations.push(item);
                }
            );
        }
    }
    function locationItem(el){
        tself = this;
        tself.id = el.id;
        tself.name = el.name;
        tself.lo_idx = el.lo_idx;
        tself.cls = ko.observable(el.cls);
    }

    function Location(item){
        kself = this;
        kself.using_id = 0;
        kself.using_name = item[0].location_type;
        kself.cls = ko.observable('jcsik jactive jsminimize');
        kself.locations = [
            new locationItem({id: 0, name: item[0].location_type, lo_idx: 0, cls: ''}),
            new locationItem({id: 1, name: 'Не выбрано', lo_idx: 0, cls: 'jexpand'})

        ];
        $.each(item, function(i, el){
            kself.locations.push(new locationItem(el));
        });
        kself.getLocation = function(){
            return kself;
        }
    }

You are binding oid property outside foreach loop which causes the break..

You can change approach and do something like

<script type="text/html" id="location-filter">


        <div>
            <ul data-bind="foreach: locations">
                <li>
                   <span data-bind="text: oid"></span> : 
                   <span data-bind="text: name, click: $parent.applyFilter(id, name, $parent)"></span>
                </li>

            </ul>
        </div>
    </div>
</script>

First your oid is outside of your foreach loop, so the binding does not have access to it at that point, secondly if you want to update the oid from js it needs to be an observable

Two options.

  1. use ko.mapping plugin to convert the properties into knockout observables

    function OutletsView(){ self = this; self.locations = ko.observableArray(ko.mapping.fromJS()); }

You will need to reference the ko.mapping.js plugin, downside to this is it converts all properties to ko properties

  1. create your own conversion method to convert the properties that you want to be observable.

something like this

function OutletsView(){
  self = this;
  self.locations = ko.observableArray(toKO(<?php echo json_encode($locations); ?>));
}

function toKO(arr){
    var retObj = []
    for(var i = 0; arr.length, i++){
       retObj.push([
         name: ko.observable(arr[i].name)
         oid: ko.observable(oid);
         /// and on and on
       });
   }
   return retObj;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM