javascript - knockout.js-मोडल के लिए स्थगित डेटाबेसिंग?




dialog modal-dialog (2)

JSFiddle @Romanych द्वारा प्रदान किए गए उत्तर में जुड़ा था अब और काम करने के लिए नहीं लग रहे थे।

इसलिए, मैंने सीआरयूडी समर्थन और मूलभूत मान्यता के साथ बूटस्ट्रैप 3 और बूटस्ट्रैप मॉडल लाइब्रेरी का उपयोग करते हुए अपना स्वयं का उदाहरण (अपने मूल बेला के आधार पर) बनाया : https://jsfiddle.net/BitWiseGuy/4u5egybp/

कस्टम बाध्यकारी हैंडलर

ko.bindingHandlers['modal'] = {
  init: function(element, valueAccessor, allBindingsAccessor) {
    var allBindings = allBindingsAccessor();
    var $element = $(element);
    $element.addClass('hide modal');

    if (allBindings.modalOptions && allBindings.modalOptions.beforeClose) {
      $element.on('hide', function() {
        var value = ko.utils.unwrapObservable(valueAccessor());
        return allBindings.modalOptions.beforeClose(value);
      });
    }
  },
  update: function(element, valueAccessor) {
    var value = ko.utils.unwrapObservable(valueAccessor());
    if (value) {
      $(element).removeClass('hide').modal('show');
    } else {
      $(element).modal('hide');
    }
  }
};

उदाहरण उपयोग

देखें

<div data-bind="modal: UserBeingEdited" class="fade" role="dialog" tabindex="-1">
  <form data-bind="submit: $root.SaveUser">
    <div class="modal-header">
      <a class="close" data-dismiss="modal">×</a>
      <h3>User Details</h3>
    </div>
    <div class="modal-body">
      <div class="form-group">
        <label for="NameInput">Name</label>
        <input type="text" class="form-control" id="NameInput" placeholder="User's name"
           data-bind="value: UserBeingEdited() && UserBeingEdited().Name, valueUpdate: 'afterkeydown'">
      </div>
      <div class="form-group">
        <label for="AgeInput">Age</label>
        <input type="text" class="form-control" id="AgeInput" placeholder="User's age"
           data-bind="value: UserBeingEdited() && UserBeingEdited().Age, valueUpdate: 'afterkeydown'">
      </div>
      <!-- ko if: ValidationErrors() && ValidationErrors().length > 0 -->
      <div class="alert alert-danger" style="margin: 20px 0 0">
        Please correct the following errors:
        <ul data-bind="foreach: { data: ValidationErrors, as: 'errorMessage'     }">
          <li data-bind="text: errorMessage"></li>
        </ul>
      </div>
      <!-- /ko -->
    </div>
    <div class="modal-footer">
      <button type="button" data-dismiss="modal" class="btn btn-default">Cancel</button>
      <button type="submit" class="btn btn-primary">Save Changes</button>
    </div>
  </form>
</div>

देखेंमोडेल

/* ViewModel for the individual records in our collection. */
var User = function(name, age) {
  var self = this;
  self.Name = ko.observable(ko.utils.unwrapObservable(name));
  self.Age = ko.observable(ko.utils.unwrapObservable(age));
}

/* The page's main ViewModel. */
var ViewModel = function() {
  var self = this;
  self.Users = ko.observableArray();

  self.ValidationErrors = ko.observableArray([]);

  // Logic to ensure that user being edited is in a valid state
  self.ValidateUser = function(user) {
    if (!user) {
      return false;
    }

    var currentUser = ko.utils.unwrapObservable(user);
    var currentName = ko.utils.unwrapObservable(currentUser.Name);
    var currentAge = ko.utils.unwrapObservable(currentUser.Age);

    self.ValidationErrors.removeAll(); // Clear out any previous errors

    if (!currentName)
      self.ValidationErrors.push("The user's name is required.");

    if (!currentAge) {
      self.ValidationErrors.push("Please enter the user's age.");
    } else { // Just some arbitrary checks here...
      if (Number(currentAge) == currentAge && currentAge % 1 === 0) { // is a whole number
        if (currentAge < 2) {
          self.ValidationErrors.push("The user's age must be 2 or greater.");
        } else if (currentAge > 99) {
          self.ValidationErrors.push("The user's age must be 99 or less.");
        }
      } else {
        self.ValidationErrors.push("Please enter a valid whole number for the user's age.");
      }
    }

    return self.ValidationErrors().length <= 0;
  };

  // The instance of the user currently being edited.
  self.UserBeingEdited = ko.observable();

  // Used to keep a reference back to the original user record being edited
  self.OriginalUserInstance = ko.observable();

  self.AddNewUser = function() {
    // Load up a new user instance to be edited
    self.UserBeingEdited(new User());
    self.OriginalUserInstance(undefined);
  };

  self.EditUser = function(user) {
    // Keep a copy of the original instance so we don't modify it's values in the editor
    self.OriginalUserInstance(user);

    // Copy the user data into a new instance for editing
    self.UserBeingEdited(new User(user.Name, user.Age));
  };

  // Save the changes back to the original instance in the collection.
  self.SaveUser = function() {
    var updatedUser = ko.utils.unwrapObservable(self.UserBeingEdited);

    if (!self.ValidateUser(updatedUser)) {
      // Don't allow users to save users that aren't valid
      return false;
    }

    var userName = ko.utils.unwrapObservable(updatedUser.Name);
    var userAge = ko.utils.unwrapObservable(updatedUser.Age);

    if (self.OriginalUserInstance() === undefined) {
      // Adding a new user
      self.Users.push(new User(userName, userAge));
    } else {
      // Updating an existing user
      self.OriginalUserInstance().Name(userName);
      self.OriginalUserInstance().Age(userAge);
    }

    // Clear out any reference to a user being edited
    self.UserBeingEdited(undefined);
    self.OriginalUserInstance(undefined);
  }

  // Remove the selected user from the collection
  self.DeleteUser = function(user) {
    if (!user) {
      return falase;
    }

    var userName = ko.utils.unwrapObservable(ko.utils.unwrapObservable(user).Name);

    // We could use another modal here to display a prettier dialog, but for the
    // sake of simplicity, we're just using the browser's built-in functionality.
    if (confirm('Are you sure that you want to delete ' + userName + '?')) {
      // Find the index of the current user and remove them from the array
      var index = self.Users.indexOf(user);
      if (index > -1) {
        self.Users.splice(index, 1);
      }
    }
  };
}

व्यू और व्यूमोल्ड के साथ नॉकआउट शुरू करना

var viewModel = new ViewModel();

// Populate the ViewModel with some dummy data
for (var i = 1; i <= 10; i++) {
  var letter = String.fromCharCode(i + 64);
  var userName = 'User ' + letter;
  var userAge = i * 2;
  viewModel.Users.push(new User(userName, userAge));
}

// Let Knockout do its magic!
ko.applyBindings(viewModel);

कर्मचारियों की सूची प्रदर्शित करने के लिए मैं knockout.js का उपयोग कर रहा हूं I मेरे पास पृष्ठ पर एक छिपा मोडल मार्कअप है जब एक कर्मचारी के लिए "विवरण" बटन क्लिक किया जाता है, तो मैं उस कर्मचारी को मोडल पॉपअप को डाटा-बाइंड करना चाहता हूं। मैं ko.applyBindings (कर्मचारी, तत्व) का उपयोग कर रहा हूं लेकिन समस्या यह है कि जब पृष्ठ लोड होता है, तो यह अपेक्षा है कि कुछ को बाध्य करने के लिए मोडल शुरू हो जाए।

तो मैं सोच रहा हूं, क्या एक देर / स्थगित डाटाबेस करने के लिए एक चाल / रणनीति है? मैं आभासी बाइंडिंग में देखा लेकिन दस्तावेज़ीकरण पर्याप्त नहीं था।

धन्यवाद!


मैं MVVVM में मोडल्स के साथ काम करने का एक अलग तरीका प्रस्तावित करना चाहता हूं। एमवीवीएम में, व्यू मॉोडल दृश्य के लिए डेटा है, और यूआई के लिए दृश्य जिम्मेदार है। यदि हम इस प्रस्ताव की जांच करते हैं:

this.detailedEmployee = ko.observable({}),

var self = this;
this.showDetails = function(employee){
    self.detailedEmployee(employee);
    $("#dialog").dialog("show"); //or however your dialog works
}

मैं दृढ़ता से इस। से सहमत this.detailedEmployee = ko.observable({}) , लेकिन मैं इस रेखा से मजबूत असहमति में हूं: $("#dialog").dialog("show"); । यह कोड ViewModel में रखा गया है और मोडल विंडो को दिखाता है, जिसमें यह दृश्य की ज़िम्मेदारी है, इसलिए हम एमवीवीएम दृष्टिकोण को स्क्रू-अप करते हैं। मैं कहूंगा कि कोड का यह टुकड़ा आपके वर्तमान कार्य को हल करेगा लेकिन यह भविष्य में बहुत सारी समस्याएं पैदा कर सकता है।

  • पॉपअप बंद करने पर, आपको अपने मुख्य ViewModel को एक सुसंगत स्थिति में रखने के लिए undefined करने के लिए detailedEmployee undefined को सेट करना चाहिए।
  • पॉपअप बंद करने पर, आप सत्यापन में और जब आप अनुप्रयोग में किसी अन्य मोडल के घटक का उपयोग करना चाहते हैं, तो क्लोज़ ऑपरेशन को छोड़ने की संभावना हो सकती है

मेरे लिए, ये बिंदु बहुत महत्वपूर्ण हैं, इसलिए मैं एक अलग तरीके से प्रस्ताव करना चाहता हूं। अगर हम "भूल जाते हैं" कि आपको पॉपअप में डेटा प्रदर्शित करने की आवश्यकता है, तो बाध्यकारी आपकी समस्या को हल कर सकती है।

this.detailedEmployee = ko.observable(undefined);
var self = this;
this.showDetails = function(employee){
    self.detailedEmployee(employee);
}

<div data-bind="with: detailedEmployee">
Data to show
</div>

जैसा कि आप देख सकते हैं, आपके व्यूमोल्ड को कुछ भी नहीं पता है कि डेटा कैसे दिखाया जाना चाहिए। यह केवल उन डेटा के बारे में जानता है जिन्हें दिखाया जाना चाहिए। बाइंडिंग के with ही सामग्री प्रदर्शित होगी, जब detailedEmployee को परिभाषित किया जाता है। इसके बाद, हमें बाध्यकारी के with मिलना चाहिए, लेकिन एक जो पॉपअप में सामग्री प्रदर्शित करेगा। आइए इसे नाम का modal । इसका कोड ऐसा है:

ko.bindingHandlers['modal'] = {
    init: function(element) {
        $(element).modal('init');
        return ko.bindingHandlers['with'].init.apply(this, arguments);
    },
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var returnValue = ko.bindingHandlers['with'].update.apply(this, arguments);

        if (value) {
            $(element).modal('show');
        } else {
            $(element).modal('hide');
        }

        return returnValue;
    }
};

जैसा कि आप देख सकते हैं, यह आंतरिक रूप with प्लगइन के with उपयोग करता है, और बाध्यकारी मान को पारित करने के आधार पर पॉपअप दिखाता है या छुपाता है। यदि यह परिभाषित किया गया है - 'शो' यदि नहीं - 'छुपाएं' इसका उपयोग इस प्रकार होगा:

<div data-bind="modal: detailedEmployee">
    Data to show
</div>

आपको केवल एक ही चीज़ अपने मनपसंद modals प्लगइन का उपयोग करना है मैंने ट्विटर बूटस्ट्रैप पॉपअप घटक के साथ एक उदाहरण तैयार किया: http://jsfiddle.net/euvNr/embedded/result/

इस उदाहरण में, कस्टम बाध्यकारी थोड़ा अधिक शक्तिशाली है; आप onBeforeClose घटना की सदस्यता ले सकते हैं और यदि आवश्यक हो तो इस ईवेंट को रद्द कर सकते हैं। उम्मीद है की यह मदद करेगा।





late-binding