1
votes

I have a component setup to use AMD to get the html template and viewmodel code. Everything works fine. The component loads when it is supposed to and behaves fine with the params passed to it. The problem is I defined an observable in the viewModel whose value shows up in the template view, but when the observable's value changes the text on the view does NOT change. Can anyone explain what is going on here? The text I am trying to bind to is modalTitle. When the modal loads its title is 'TEMP' but if I go to the console and type 'window.modalTitle()' I get 'CREATE REPORT SCHEDULE'. It's like the view is getting the first value of the observable and then ignoring it after that. Is there anyway I can force it to look for updates?

ViewModel: (schedules.component.js)

  define(['knockout'], function (ko) {
  console.log('schedules hit');
  loadCss('schedules');

  function SchedulesViewModel(params) {
    this.scheduledItems = params.scheduledItems;
    this.itemName = params.itemName;
    this.modalTitle = ko.observable("TEMP");
    window.modalTitle = this.modalTitle;
  }

  SchedulesViewModel.prototype.initiateAddScheduledItem = function () {
    this.modalTitle("CREATE " + this.itemName + " SCHEDULE");
    $('#schedulesModal').modal('show');
  };

  SchedulesViewModel.prototype.removeSelectedScheduledItem = function () {
    this.chosenValue('dislike');
  };

  window.ReportsApp.SchedulesViewModel = SchedulesViewModel;

  return SchedulesViewModel;
});

View Template

<div id="schedulesModal" class="modal fade lcmsModal" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <!--<button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>-->
        <img src="/Content/images/modalASLogo.png" style="float: right;" />
        <h4 class="modal-title" data-bind="text: modalTitle()">Test Title</h4>
      </div>
      <div class="modal-body">
        <p>One fine body ...</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">CANCEL</button>
        <button type="button" class="btn btn-primary">SAVE</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- /Bootstrap Modal -->
1

1 Answers

2
votes

It does not get changed because this.itemName has not been defined as an observable. it is better to define a computed observable which will automatically update whenever any observables change.
Instead of using prototype to add methods, you can use knockout function which foes it for you. Example :https://jsfiddle.net/kyr6w2x3/34/

 function SchedulesViewModel(params) {
    var self = this ;
    self.scheduledItems = ko.observable(params.scheduledItems);
    self.itemName = ko.observable(params.itemName);
    self.modalTitle = ko.observable("TEMP");
    self.chosenValue= ko.observable();

   self.modalTitle = ko.computed(function() {
        return "CREATE " + self.itemName() + " SCHEDULE" ;
    }, self);

    // you can change below to show your modal whenever you want
    $('#schedulesModal').modal('show');

    self.removeSelectedScheduledItem = function (){
        self.chosenValue('dislike');
    }
  }


ko.applyBindings(new SchedulesViewModel({scheduledItems:"scheduledItems" ,itemName : "itemName" }));

Update : yes you can have multiple view models or better to say nested view models. Look at the new example and see how you can communicate between your models.https://jsfiddle.net/kyr6w2x3/35/