简体   繁体   中英

Passing variables between KnockoutJS and AngularJS

  1. I am using Knockout in my SPA dashboard creation. Its working good.But we need to add more and more complex things in our dashboard, so we planned to develop the remaining part of dashboard in Angular.

  2. My question is how can i pass variables from knockout to Angular. I tried using set and get methods, but it didn't helped me.. 3.So, i tried like this, i would like to set an attribute value in the ko function when, like this..

<li id="setMgmtEnv">
  <a href='javascript:;' data-bind="click: setMgmtEnv">
    <span>Manage Orgs</span>
  </a>
</li>
///////in Main JS file
var x = document.getElementById("setMgmtEnv"); 
        x.setAttribute("value", "0");
    ////// In KO model
    self.setMgmtEnv =  function(){
                x.setAttribute("value", "1");           
            }
    ///////// In Angular i am noticing the change variable like this
   $scope.$watch(function(load) {
    return $scope.toLoad = document.getElementById('setMgmtEnv').value;
}, function(newValue, oldValue) {
    console.log("$scope.toLoad2 : " + $scope.toLoad);
    if ($scope.toLoad) {
        console.log("$scope.toLoad3 : " + $scope.toLoad);
        $http({
            method : 'GET',
            url : url
        }).success(function(data) {
            console.log(data);
        }).error(function(data) {
            alert("Failure message: " + JSON.stringify({
                data : data
            }));
        });
    }}

Mixing KnockoutJS and AngularJS in one application is a big red flag. Be sure you understand what you're doing, or you'll probably be better off rewriting the KO parts in Angular.

Having said that, I can try to answer the question you're asking, though not in the context of the code snippet you provided (which is very unclear).

There are three main ways KO can interact with Angular (which is the direction you seem to be asking about):

  1. They each control their own piece of the DOM. KO will "notify" Angular through Javascript code. This would be the preferred situation.
  2. They each control their own piece of the DOM. KO will "notify" Angular by influencing a piece of the DOM actually controlled by Angular.
  3. They have shared control of the same piece of the DOM. KO "notifies" Angular automatically because it will update the DOM when a variable changes, and Angular's two-way bindings pick this up.

Option 2 and 3 are a recipe for disaster. They can be done, but are that bad I'll leave creating a PoC as an excercise for the reader.

That leaves option 1, which in specific cases can actually be useful. To do so you need these ingredients:

  • Within Angular's scope a reference to the KO ViewModel;
  • A subscription on the relevant part of KO's ViewModel;
  • A call to $scope.$apply no notify Angular the KO subscription callback has changed the scope.

Here's an exmaple:

 var ViewModel = function() { this.name = ko.observable(""); }; var vm = new ViewModel(); angular.module("demoApp", []) .controller("myCtrl", ["$scope", function($scope) { $scope.name = vm.name(); vm.name.subscribe(function(newVal) { $scope.$apply(function() { $scope.name = newVal; }); }); }]); ko.applyBindings(vm, document.getElementById("knockoutArea")); 
 div { margin: 5px; padding: 5px; border: 1px solid #edd; background-color: #fee; } 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <div id="knockoutArea"> <strong>Knockout</strong><br> Type your name: <input data-bind="textInput: name"> </div> <div id="angularArea" ng-app="demoApp" ng-controller="myCtrl"> <strong>Angular</strong><br> We know your name is: <strong>{{ name }}</strong> </div> 

As an alternative, given that Angular seems to be your way forward, you may want to invert the dependency. Give KO a reference to Angular and make that "legacy" part of your code call updates on the Angular scopes. This makes your KO code a lot dirtier, but keeps your future codebase cleaner.

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