调用Ko.Observable数组中的函数该怎么做? Knockout

huangapple go评论52阅读模式
英文:

How to Call A Function inside a Ko.Observable Array? Knockout

问题

I'm learning more about knockout.js. I have built a little dialogue system using it and it works! One thing I'd like to do is have a function that can jump from the data after a button is pressed to run a new function.


How the data below works is there's text that shows, the image changes, and the choices are buttons that when pressed go to the next story/data set. In this case, it goes back to the start (storyLink 1).

Here's a snippet of my data with said function:

 "106":{"text":"[The game ended you Died.]",
  "image": "death face.gif",
  "choices":[{"choiceText":"Oops.","storyLink":"1", function () { console.log("lmao");}}]},

Here is a snippet of the HTML:

    <div data-bind="with: activeStory">
    <img data-bind="attr: { src: image }">
<button id="button" class="Button-data imgLink" onclick="handleClick()" data-bind="click: $root.onChoice, text: choiceText"></button>

Here's a bit of the view model. I did not include the part where the bindings are applied, as that's a chunk of code that takes the text above and creates a typewriter effect:

var activeStoryId = ko.observable(1)

  .extend({ notify: "always" });
  
  var activeStory = ko.pureComputed(() => 
  story[activeStoryId()] ?? 

  { text: "[There was an Error.]", choices: [{ choiceText: "Back to start", storyLink: 1 }] }
);

var onChoice = ({ storyLink }) => activeStoryId(storyLink);

    // Apply bindings
      registerBinding();
      ko.applyBindings({
        onChoice,
        activeStory
      });

This isn't running, and I assume this is because of a syntax error or perhaps I need to call it a different way. I keep finding my syntax is wrong when using knockout, so any insight would be great!

Edit 2:
Here's an example of what I am trying to figure out:

let a = 1;
let b = 2;

let arr = [
  a,
  b,
  function () {
    return a + b;
   },
  ];

console.log(arr[2]()); // returns 3
console.log(typeof arr); // returns object

In this code, there's a function that runs inside the array. It doesn't currently work in my code when I try to do this.

英文:

I'm learning more about knockout.js. I have built a little dialogue system using it and it works! One thing I'd like to do, is have a function that can jump from the data after a button is pressed to run a new function.


How the data below works is there's text that shows, the image changes, and the choices are buttons that when pressed go to the next story/data set. In this case it goes back to the start (storyLink 1).

Here's a snippet of my data with said function:

 &quot;106&quot;:{&quot;text&quot;:&quot;[The game ended you Died.]&quot;,
  &quot;image&quot;: &quot;death face.gif&quot;,
  &quot;choices&quot;:[{&quot;choiceText&quot;:&quot;Oops.&quot;,&quot;storyLink&quot;:&quot;1&quot;, function () { console.log(&quot;lmao&quot;);}}]},

here is a snippet of the html:

    &lt;div data-bind=&quot;with: activeStory&quot;&gt;
    &lt;img data-bind=&quot;attr: { src: image }&quot;&gt;
&lt;button id =&quot;button&quot; class =&quot;Button-data imgLink&quot; onclick = &quot;handleClick()&quot; data-bind=&quot;click: $root.onChoice, text: choiceText&quot;&gt;&lt;/button&gt;

here's a bit of the view model. I did not include the part where the bindings are applied as that's a chunk of code that takes the text above and creates a typewriter effect.

var activeStoryId = ko.observable(1)

  .extend({ notify: &quot;always&quot; });
  
  var activeStory = ko.pureComputed(() =&gt; 
  story[activeStoryId()] ?? 

  { text: &quot;[There was an Error.]&quot;, choices: [{ choiceText: &quot;Back to start&quot;, storyLink: 1 }] }
);

var onChoice = ({ storyLink }) =&gt; activeStoryId(storyLink);

    // Apply bindings
      registerBinding();
      ko.applyBindings({
        onChoice,
        activeStory
      });

This isn't running, and I assume this is because of a syntax error or perhaps I need to call it a different way. I keep finding my syntax is wrong when using knockout so any insight would be great!

I tried adjusting the syntax based on Javascript arrays and I'm still missing something. I haven't found a solution that works yet.

Edit 2:
Here's an example of what I am trying to figure out:

let a = 1;
let b = 2;

let arr = [
  a,
  b,
  function () {
    return a + b;
   },
  ];

console.log(arr[2]()); // return 3
console.log(typeof arr); // returns object

In this code, there's a function that runs inside the array. It doesn't currently work in my code when I try to do this.

答案1

得分: 1

Here is the translated content:

我认为我理解了你想要做什么。希望这会有所帮助。

var story = {
   "1": {
      "text": "[游戏结束,你死了。]",
      "image": "death_face.gif",
      "choices": [{
         "choiceText": "糟糕。",
         "storyLink": "1"
      }, {
         "choiceText": "差一点……",
         "storyLink": "2"
      }]
   },
   "2": {
      "text": "[开始新故事]",
      "image": "happy_face.gif",
      "choices": [{
         "choiceText": "我们走吧。",
         "storyLink": "1"
      }, {
         "choiceText": "也许下次吧。",
         "storyLink": "2"
      }]
   }
};

function ViewModel() {
   var self = this;
   self.activeStoryId = ko.observable(1)
      .extend({
         notify: "always"
      });

   self.activeStory = ko.pureComputed(() =>
      story[self.activeStoryId()] ?? {
         text: "[发生了错误。]",
         choices: [{
            choiceText: "回到起点",
            storyLink: 1
         }]
      }
   );

   self.onChoice = function(item) {
      console.log(item);
      self.activeStoryId(item.storyLink);
   }
}

var vm = new ViewModel();

ko.applyBindings(vm);

如果我理解正确,如果你想要将函数作为数据的一部分传递,你可以像下面这样做。拥有一个在你的选择对象之间相同的函数名称,然后你可以将该函数对象传递给click绑定以运行它。

var story = {
   "1": {
      "text": "[游戏结束,你死了。]",
      "image": "death_face.gif",
      "choices": [{
         "choiceText": "糟糕。",
         "storyLink": "1",
         "choiceCommand": function () { console.log("storylink 1-1") }
      }, {
         "choiceText": "差一点……",
         "storyLink": "2",
         "choiceCommand": function () { console.log("storylink 1-2") }
      }]
   },
   "2": {
      "text": "[开始新故事]",
      "image": "happy_face.gif",
      "choices": [{
         "choiceText": "我们走吧。",
         "storyLink": "1",
         "choiceCommand": function () { console.log("storylink 2-1") }
      }, {
         "choiceText": "也许下次吧。",
         "storyLink": "2",
         "choiceCommand": function () { console.log("storylink 2-2") }
      }]
   }
};

希望这对你有所帮助!

英文:

I think I understand what you are tying to do. Hopefully this will help.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

var story = {
  &quot;1&quot;: {
    &quot;text&quot;: &quot;[The game ended you Died.]&quot;,
    &quot;image&quot;: &quot;death_face.gif&quot;,
    &quot;choices&quot;: [{
      &quot;choiceText&quot;: &quot;Oops.&quot;,
      &quot;storyLink&quot;: &quot;1&quot;
    }, {
      &quot;choiceText&quot;: &quot;So close...&quot;,
      &quot;storyLink&quot;: &quot;2&quot;
    }]
  },
  &quot;2&quot;: {
    &quot;text&quot;: &quot;[Start New Story]&quot;,
    &quot;image&quot;: &quot;happy_face.gif&quot;,
    &quot;choices&quot;: [{
      &quot;choiceText&quot;: &quot;Away we go.&quot;,
      &quot;storyLink&quot;: &quot;1&quot;
    }, {
      &quot;choiceText&quot;: &quot;Maybe next time&quot;,
      &quot;storyLink&quot;: &quot;2&quot;
    }]
  }
};

function ViewModel() {
  var self = this;
  self.activeStoryId = ko.observable(1)
    .extend({
      notify: &quot;always&quot;
    });

  self.activeStory = ko.pureComputed(() =&gt;
    story[self.activeStoryId()] ?? {
      text: &quot;[There was an Error.]&quot;,
      choices: [{
        choiceText: &quot;Back to start&quot;,
        storyLink: 1
      }]
    }
  );

  self.onChoice = function(item) {
    console.log(item);
    self.activeStoryId(item.storyLink);
  }
}

var vm = new ViewModel();

ko.applyBindings(vm);

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js&quot;&gt;&lt;/script&gt;
&lt;div data-bind=&quot;with: activeStory&quot;&gt;
  &lt;h2 data-bind=&quot;text: text&quot;&gt;&lt;/h2&gt;
  &lt;img data-bind=&quot;attr: { src: image }&quot;&gt;
  &lt;!-- ko foreach: choices --&gt;
  &lt;button id=&quot;button&quot; class=&quot;Button-data imgLink&quot; data-bind=&quot;click: $root.onChoice, text: choiceText&quot;&gt;&lt;/button&gt;
  &lt;!-- /ko --&gt;
&lt;/div&gt;

<!-- end snippet -->

EDIT
If I understand correctly, if you want to be passing functions as part of your data, I would do something like the following. Have a function name that is the same across your choice objects. then you can pass that function object to the click binding for it to run.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

var story = {
  &quot;1&quot;: {
    &quot;text&quot;: &quot;[The game ended you Died.]&quot;,
    &quot;image&quot;: &quot;death_face.gif&quot;,
    &quot;choices&quot;: [{
      &quot;choiceText&quot;: &quot;Oops.&quot;,
      &quot;storyLink&quot;: &quot;1&quot;,
      &quot;choiceCommand&quot;: function () { console.log(&quot;storylink 1-1&quot;)}
    }, {
      &quot;choiceText&quot;: &quot;So close...&quot;,
      &quot;storyLink&quot;: &quot;2&quot;,
      &quot;choiceCommand&quot;: function () { console.log(&quot;storylink 1-2&quot;)}
    }]
  },
  &quot;2&quot;: {
    &quot;text&quot;: &quot;[Start New Story]&quot;,
    &quot;image&quot;: &quot;happy_face.gif&quot;,
    &quot;choices&quot;: [{
      &quot;choiceText&quot;: &quot;Away we go.&quot;,
      &quot;storyLink&quot;: &quot;1&quot;,
      &quot;choiceCommand&quot;: function () { console.log(&quot;storylink 2-1&quot;)}
    }, {
      &quot;choiceText&quot;: &quot;Maybe next time&quot;,
      &quot;storyLink&quot;: &quot;2&quot;,
      &quot;choiceCommand&quot;: function () { console.log(&quot;storylink 2-2&quot;)}
    }]
  }
};

function ViewModel() {
  var self = this;
  self.activeStoryId = ko.observable(1)
    .extend({
      notify: &quot;always&quot;
    });

  self.activeStory = ko.pureComputed(() =&gt;
    story[self.activeStoryId()] ?? {
      text: &quot;[There was an Error.]&quot;,
      choices: [{
        choiceText: &quot;Back to start&quot;,
        storyLink: 1
      }]
    }
  );

  self.onChoice = function(item) {
    console.log(item);
    self.activeStoryId(item.storyLink);
  }
}

var vm = new ViewModel();

ko.applyBindings(vm);

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js&quot;&gt;&lt;/script&gt;
&lt;div data-bind=&quot;with: activeStory&quot;&gt;
  &lt;h2 data-bind=&quot;text: text&quot;&gt;&lt;/h2&gt;
  &lt;img data-bind=&quot;attr: { src: image }&quot;&gt;
  &lt;!-- ko foreach: choices --&gt;
  &lt;button id=&quot;button&quot; class=&quot;Button-data imgLink&quot; data-bind=&quot;click: choiceCommand, text: choiceText&quot;&gt;&lt;/button&gt;
  &lt;!-- /ko --&gt;
&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年4月17日 02:20:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76029576.html
  • javascript
  • knockout.js

在Nunjucks模板中访问数组在 :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定