草庐IT

javascript - 范围变量值的变化没有反射(reflect)在我的字符串中

coder 2024-07-25 原文

我有以下字符串:

"/root/get";

现在我在上面的字符串中生成一个带有 1 个范围变量的查询字符串,但问题是当该变量的值发生变化时,新值不会自动在我的 URL 中更新。

您可以在下面的演示中看到我有 2 个按钮更新和检查。在更新中,我生成了查询字符串,并在检查按钮上更新了范围变量的值,但这并没有反射(reflect)在我的 URL 中。

我不明白为什么会这样。

在不调用 generateQueryParameters 方法的情况下单击复选按钮时的预期输出:

/root/get?no=2

var app = angular.module("myApp", []);
        app.controller("myController", function ($scope) {
        
        $scope.no = 1;
        $scope.str = "/root/get";
     
        $scope.update = function (data) {
          $scope.str=generateQueryParameters($scope.str,
               "no",$scope.no);
               console.log($scope.str);
        };
           

            $scope.check = function () {
              $scope.no=2;
              console.log($scope.str);
            };
               
    function generateQueryParameters(url,name,value)
    {
        var re = new RegExp("([?&]" + name + "=)[^&]+", "");
        function add(sep) {
            url += sep + name + "=" + encodeURIComponent(value);
        }
        function change() {
            url = url.replace(re, "$1" + encodeURIComponent(value));
        }
        if (url.indexOf("?") === -1) {
            add("?");
        } else {
            if (re.test(url)) {
                change();
            } else {
                add("&");
            }
        }
        return url;
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
    <input type="button" value="Update" ng-click="update()">
    <input type="button" value="Check" ng-click="check()">
</div>

更新: 我知道 $scope.no 的值何时会改变,所以我认为我不需要 watcher 并且我不想再次调用 generateParameters .为什么 Angular 不像 Angular 绑定(bind)那样自动更新我的 str 中的值?

最佳答案

让我们从您的代码中的问题开始。您通过一个函数生成请求字符串,该函数实际上只在 update 函数中调用

$scope.update = function(data) {
  $scope.str = generateQueryParameters($scope.str,
    "no", $scope.no);
  console.log($scope.str);
};


$scope.check = function() {
  $scope.no = 2;
  console.log($scope.str);
};

您在 check 函数中更改了版本号,但没有再次调用该函数以更改 $scope.str,因此 的值$scope.str 还是一样的。

您可以通过在您的代码段中执行以下步骤轻松地对此进行测试:

  1. 点击更新(v0)

  2. 点击检查(v0)

  3. 但是然后再次点击更新,你会看到现在它已经更新了(v2)

因此在第 2 步中您实际上更改了版本,您只是不再生成要使用的 str

代码的简单修复就是简单地安排代码以便在每次更改版本时调用分配新 str 的函数:

$scope.update = function(data) {
  $scope.no = 1;
  $scope.str = generateQueryParameters($scope.str,
    "no", $scope.no);
  console.log($scope.str);
};


$scope.check = function() {
  $scope.no = 2;
  // here you need to call again your function for composing your URL and changing the value of str
  $scope.str = generateQueryParameters($scope.str,
    "no", $scope.no);
  console.log($scope.str);
};

function generateStringRequest() {

}

否则需要在no版本参数上监听,每次版本变化时自动刷新str值。但是这个解决方案意味着您将在调用 API 的每个 Controller 中都有一个观察者,并且所有参数总是硬编码在 Controller 中:

$scope.$watch('no', function() {
    $scope.str = generateQueryParameters($scope.str, 'no', $scope.no);
});

即使这个解决方案有效,实际上也很糟糕。 管理调用的逻辑在 Controller 内部,这是一个非常糟糕的做法(您应该考虑为此使用集中式服务)。

好多了,在 AngularJS 中,您可以使用自定义拦截器并在那里管理要执行的所有关于 HTTP 请求的操作。 因此,您可以将要使用的 API 版本指定为 HTTP 请求的参数。

这将使您的代码保持整洁。此外,如果您以后想更改某些请求,只需更改该请求参数即可。 如果你想改变所有的请求,在拦截器中你可以简单地设置所有对 version 1 的请求将被替换为 version 2

这里是一个关于如何定义拦截器的示例代码:

angular.module('myApp').factory('MyHTTPFactory', MyHTTPFactory)
  .config(function($httpProvider) {
    // register the new interceptor in AngularJS
    $httpProvider.interceptors.push('MyHTTPFactory');
  });

MyHTTPFactory.$inject = [];

function MyHTTPFactory() {

  // this is the base URL of your rest requests, so this interceptor will be applied only to the requests directed to your service
  const MY_REST_URL = 'blablabla';

  // methods exposed by the service
  let factory = {
    request: request,
    requestError: requestError,
    response: response,
    responseError: responseError
  };
  return factory;

  // ============================================================


  function request(config) {
    if (config.url.includes(MY_REST_URL)) {
      let versionToUse = config.version;
      // here use a function for elaborating your query string, directly in the interecptor code
      config.url = elaborateQueryString();
    }
    return config;
  }

  function requestError(config) {
    return config;
  }

  function response(res) {
    return res;
  }

  function responseError(res) {
    return res;
  }

  // function for getting the query string you want to
  function elaborateQueryString() {
    // elaborate your requests
  }

}

然后通过 $http 像往常一样简单地执行 HTTP 请求,在请求中添加您要使用的版本作为参数:

// perform your request as usual simply specifying the new version parameter
let request = {
  url: `myserviceurl`,
  version: '2' // or whatever you qNR
};
$http(request);

因此拦截器会在执行之前“嗅探”您的所有请求,它会根据您的需要正确组合版本和查询字符串,并且您的所有操作都在其中进行管理和集中处理。

就像上一个提示一样,在定义诸如版本号、其余服务的端点等常量时,使用 AngularJS constant 并将它们注入(inject)到您需要使用它们的地方。硬编码字符串不是一个好习惯。

关于javascript - 范围变量值的变化没有反射(reflect)在我的字符串中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46055212/

有关javascript - 范围变量值的变化没有反射(reflect)在我的字符串中的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  5. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  6. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  7. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  8. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  9. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐