简体   繁体   中英

Knockout JS template attr href binding returning function instead of value

I have a template binding that looks like this:

    <div style="display: none;" data-bind="template: { name: 'info-window-template', data: currentPlace() }"></div>

    <script type="text/html" id="info-window-template">
    <div class="infobox">
        <h2 id="placeName">
            <a data-bind="data: name(), attr: { href: website() }"></a>
        </h2>
        <h4 data-bind="data: address()"></h4>
    </div>
    </script>

and

var places = [
    {
      name: "Austin Pizza Garden",
      address: "6266 Hwy 290 Austin, TX 78735",
      website: 'http://www.austin-pizza-garden.com',
    }...]

And a Model:

var Place = function(data) {
  this.name = ko.observable(data.name);
  this.address = ko.observable(data.address);
  this.website = ko.observable(data.website);
}

and ViewModel:

var ViewModel = function() {
  var self = this;
  self.placeList = ko.observableArray([]);
  places.forEach(function(placeItem) {
    self.placeList.push( new Place(placeItem) );
  });
  self.currentPlace = ko.observable( this.placeList()[0] );

The output works find for both name and address , but for website , it returns the function instead of the url, so the link doesn't work.

I get this when I run this in the browser:

<a href="function d(){if(0&lt;arguments.length)return d.Wa(c,arguments[0])&amp;&amp;(d.X(),c=arguments[0],d.W()),this;a.k.Ob(d);return c}">Austin Pizza Garden</a>

Why does knockout return the function instead of the text of the url? Why does it work for name and address but not for website ? How can I make it return the text of the url?

If you open the project link you'll see that the first infobox div thats from the html actually works perfectly, but its why it gets dynamically called in the js that it breaks.

Full code here :

Your code works.

 var Place = function (data) { this.name = ko.observable(data.name); this.address = ko.observable(data.address); this.website = ko.observable(data.website); }; var ViewModel = function (places) { var self = this; self.placeList = ko.observableArray([]); places.forEach(function (placeItem) { self.placeList.push(new Place(placeItem)); }); self.currentPlace = ko.observable(this.placeList()[0]); }; var places = [{ name: "Austin Pizza Garden", address: "6266 Hwy 290 Austin, TX 78735", website: 'http://www.austin-pizza-garden.com' }]; var vm = new ViewModel(places); ko.applyBindings(vm); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <div data-bind="template: { name: 'info-window-template', data: currentPlace }"></div> <script type="text/html" id="info-window-template"> <div class="infobox"> <h2 id="placeName"> <a data-bind="text: name, attr: { href: website }"></a> </h2> <h4 data-bind="text: address"></h4> </div> </script> 

You might want to use the text binding, though. There is no data binding. (Hint: If you did use the text binding in your real code, post your real code next time, not something you just made up.)

You don't need to use any parentheses, either. Knockout unwraps any observables automatically for you during data binding.

However, if you see function d(){... as the value of any data-bound property, then you are looking at an observable erroneously wrapped in an observable. In this case you should check your viewmodel building process to make sure no y in any this.x = ko.observable(y) is already observable itself.

Try to remove parentheses

    <script type="text/html" id="info-window-template">
<div class="infobox">
    <h2 id="placeName">
        <a data-bind="data: name, attr: { href: website }"></a>
    </h2>
    <h4 data-bind="data: address"></h4>
</div>
</script>

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