在KnockoutJS和AngularJS之间传递变量

Net*_*thi 0 angularjs knockout.js

  1. 我在我的SPA仪表板创建中使用Knockout.它的工作性很好.但我们需要在仪表板中添加越来越复杂的东西,因此我们计划在Angular中开发仪表板的剩余部分.

  2. 我的问题是如何将变量从knockout传递给Angular.我尝试使用set和get方法,但它没有帮助我.. 3.所以,我试过这样,我想在ko函数中设置一个属性值,就像这样..

<li id="setMgmtEnv">
  <a href='javascript:;' data-bind="click: setMgmtEnv">
    <span>Manage Orgs</span>
  </a>
</li>
Run Code Online (Sandbox Code Playgroud)
///////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
            }));
        });
    }}
Run Code Online (Sandbox Code Playgroud)

Jer*_*oen 7

在一个应用程序中混合使用KnockoutJS和AngularJS是一个很大的危险信号.确保你理解你在做什么,或者你可能会更好地重写Angular中的KO部分.

话虽如此,我可以尝试回答您提出的问题,但不是在您提供的代码段的背景下(这是非常不清楚的).

KO可以通过三种主要方式与Angular交互(这是您似乎要问的方向):

  1. 他们各自控制自己的DOM.KO将通过Javascript代码"通知"Angular.这将是首选的情况.
  2. 他们各自控制自己的DOM.KO将通过影响Angular实际控制的一块DOM来"通知"Angular.
  3. 他们共同控制了同一块DOM.KO"自动通知"Angular因为它会在变量发生变化时更新DOM,而Angular的双向绑定会选择它.

选项2和3是灾难的秘诀.他们可以完成,但是那很糟糕我会留下创建一个PoC作为读者的练习.

这留下了选项1,在特定情况下实际上可能是有用的.要做到这一点,你需要这些成分:

  • 在Angular的范围内,对KO ViewModel的引用;
  • 订阅KO ViewModel的相关部分;
  • 呼叫到$scope.$apply任何通知角的KO订阅回调改变了范围.

这是一个例子:

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"));
Run Code Online (Sandbox Code Playgroud)
div { margin: 5px; padding: 5px; border: 1px solid #edd; background-color: #fee; }
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

作为替代方案,鉴于Angular似乎是您的前进方向,您可能希望反转依赖关系.为KO提供对Angular的引用,并在Angular范围内为代码调用更新"遗留"部分.这使您的KO代码更脏,但保持您未来的代码库更清洁.