Angular.js: خيار على الموقع $ للسماح بتغيير التجزئة / المسار بدون إعادة تحميل المسار

تم إنشاؤها على ١٢ ديسمبر ٢٠١٢  ·  194تعليقات  ·  مصدر: angular/angular.js

لدينا نموذج في تطبيقنا حيث يقوم المستخدم بإنشاء أشياء جديدة على نفس الصفحة التي يشاهدون فيها الأشياء. إذن طريقنا يشبه / شيء /: معرف. عند إنشاء شيء جديد يذهبون إلى / شيء / جديد. بمجرد حفظ الشيء بنجاح ، نريد تغيير المسار إلى / شيء / 1234 (أو أيًا كان معرفه الجديد). الآن لا يحتاج الجزئي إلى إعادة التحميل لأن البيانات كلها متشابهة. نريد فقط تحديث المسار حتى يتمكن المستخدم الآن من وضع إشارة مرجعية على الرابط الصحيح ، وما إلى ذلك.

إن وجود خيار على موقع $ (ليس في تعريف المسار) لتمكين / تعطيل تحميل المسار سوف يعمل ولكنني متأكد من أن هناك طرقًا أخرى لتنفيذ الميزة.

Lots of comments $location ngRoute high confusing feature

التعليق الأكثر فائدة

الحل بشكل أساسي هو إضافة معامل إضافي إلى $ location.path ().

app.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
    var original = $location.path;
    $location.path = function (path, reload) {
        if (reload === false) {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
        }
        return original.apply($location, [path]);
    };
}]);

ثم استخدم فقط مثل هذا

$location.path('/path/that/you/need', false);

ال 194 كومينتر

+1 ، وجود نفس المشكلة.

cgross نظرًا لأن خدمة الموقع $ تستخدم تسلسل أسلوب JQuery ، ويتم تأجيل جميع الأوامر حتى $ Digest بأي حال ، أقترح إضافة طريقة تسلسل جديدة ، على سبيل المثال ، إعادة التحميل (منطقية):

$location.path("/thing/"+thing.id).replace().reload(false)

ملاحظة: هل هذا هو كريس جروس الذي بدأ مشروع سديم الكسوف؟

نعم :)

+1: +1:

+1

في الوقت الحالي ، نستخدم قرصنة قذرة للتغلب على هذه المشكلة.

    $scope.$on('$locationChangeSuccess', function(event) {

        // Want to prevent re-loading when going from /dataEntry/1 to some other dataEntry path
        if ($route && $route.current && $route.current.$route.templateUrl.indexOf('dataEntry') > 0) {
            $route.current = lastRoute; //Does the actual prevention of routing
        }
});

+1

+1

+1

+1

+1

هذه هي محاولتي لإصلاح هذا من خلال دعم preventDefault() مقابل $routeChangeStart . ما رأيك في ذلك؟
الالتزام: https://github.com/redhotsly/angular.js/commit/f8ac46e6ac9d76cf855077d21b68b4c2c8043db1

لقد كنت أعمل في نهج qualidafial لبضعة أيام والآن العلاقات العامة جاهزة. لقد أنشأت طريقة notify تسمح بتخطي إشعار تغيير الموقع لمرة واحدة. يجب أن يتجنب هذا إحداث أي تغيير في المسار أو إعادة تحميله.

هذا لا يمس نظام التوجيه ، لذلك ليس عليك تغيير تعريفات المسار الخاصة بك. سيستمر العمل حتى إذا كنت تستخدم ui-router بدلاً من نظام التوجيه AngularJS القياسي.

مثال: $location.path('/client/2').replace().notify(false);

لقد عملت أيضًا على بعض أجزاء الاختبارات والتوثيق.

+1

+1 آخر
استخدام طلب سحب lrlopez بالفعل. يعمل كالسحر.

+1

+1

لسوء الحظ ، تم رفض PR https://github.com/angular/angular.js/pull/2398 من قبل فريق Angular لأن تخطي الإشعارات قد يؤدي إلى تناقضات بين عنوان URL الفعلي والمسار الحالي. هناك تفسير طويل في نهاية المناقشة.

لا أحتاج إلى هذه الميزة في أي من مشاريعي ، لكنني سأحتفظ بها في مستودعي حتى يمكن دمجها إذا كنت ترغب في ذلك. فقط أعلمني إذا خرج عن المزامنة مع الفرع الرئيسي حتى أتمكن من إعادة تأسيس التغييرات. شكرا!

+1

+1 ، أحتاج هذا :(

+1

تحرير: نهج أفضل هنا: https://github.com/angular/angular.js/issues/1699#issuecomment -22511464

لقد أنشأت مصنعًا يمكن إعادة استخدامه لتجاوز هذا (بناءً على فكرة منshahmirn):

/**
 * HACK Do not reload the current template if it is not needed.
 *
 * See AngularJS: Change hash and route without completely reloading controller http://stackoverflow.com/questions/12115259/angularjs-change-hash-and-route-without-completely-reloading-controller
 */
app.factory('DoNotReloadCurrentTemplate', ['$route', function($route) {
  return function(scope) {
    var lastRoute = $route.current;
    scope.$on('$locationChangeSuccess', function() {
      if (lastRoute.$$route.templateUrl === $route.current.$$route.templateUrl) {
        console.log('DoNotReloadCurrentTemplate not reloading template: ' + $route.current.$$route.templateUrl);
        $route.current = lastRoute;
      }
    });
  };
}]);

كيف تستعمل:

app.controller('MyCtrl',
  ['$scope', 'DoNotReloadCurrentTemplate',
  function($scope, DoNotReloadCurrentTemplate) {

  DoNotReloadCurrentTemplate($scope);
}]);

المصدر: http://stackoverflow.com/a/16496112/990356

إذا قمت بتعيين "reloadOnSearch" على خطأ في المسار ، فيبدو أنه يعمل على إصلاح تغييرات التجزئة مع إعادة تحميل الصفحة بأكملها.

+1

سيكون هذا أمرًا رائعًا لتطبيقات الأجهزة المحمولة ، حيث تكون دورة حياة إنشاء / إتلاف ng-view غير مناسبة (تقضي على الأداء وسهولة الاستخدام).

tkrotoff شكرا على المثال. نظرًا لأن الحل البديل الخاص بك هو إلغاء إشعارات الأحداث ، فقد أضفت بثًا على rootcope بحيث لا يزال من الممكن إخطار وحدات التحكم الأخرى بتغيير المسار:

/**
 * HACK Do not reload the current template if it is not needed.
 *
 * See AngularJS: Change hash and route without completely reloading controller http://stackoverflow.com/questions/12115259/angularjs-change-hash-and-route-without-completely-reloading-controller
 */
app.factory('DoNotReloadCurrentTemplate', ['$route', '$rootScope', function($route, $rootScope) {
  return function(scope) {
    var lastRoute = $route.current;
    scope.$on('$locationChangeSuccess', function() {
      if (lastRoute.$$route.templateUrl === $route.current.$$route.templateUrl) {
        console.log('DoNotReloadCurrentTemplate not reloading template: ' + $route.current.$$route.templateUrl);
        $rootScope.$broadcast('locationChangedWithoutReload', $route.current);
        $route.current = lastRoute;        
      }
    });
  };
}]);

ثم:

app.controller('MyCtrl',
  ['$scope', 'DoNotReloadCurrentTemplate',
  function($scope, DoNotReloadCurrentTemplate) {

  DoNotReloadCurrentTemplate($scope);

  $rootScope.$on('locationChangedWithoutReload', function(event, route) {
    // set location specific breadcrumbs
    $scope.breadcrumbs = assembleBreadCrumbs();

    // do something for specific route
    if (route.$$route.action == 'item') {
      $scope.item = $scope.items[params.itemId];
      $rootScope.title = $scope.item.name;
    }
  });
}]);

لدي نفس المشكلة التي أنشأها مؤلف الموضوع وقمت بإنشاء نسخة معدلة من الحل الموصوف أعلاه.

app.factory('skipReload', [
    '$route',
    '$rootScope',
    function ($route, $rootScope) {
        return function () {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
        };
    }
]);

استعمال:

app.controller('ThingCtrl', ['$scope', '$http', '$location', 'skipReload', function ($scope, $http, $location, skipReload) {
    ...
    $scope.submit = function () {
        ...
        $http.post('thing', thing).success(function (id) {
            skipReload();
            $location.path('/thing/' + id).replace();
        });
    };
}]);

قد يؤدي استخدام مستمع الحدث الدائم الذي يختبر templateUrl لتحديد ما إذا كان سيتم السماح بإعادة تحميل المسار ، إلى قطع التوجيه إلى طرق العرض الأخرى التي تستخدم نفس النموذج Url. على سبيل المثال ، قمت بالتوجيه إلى / شيء / جديد ويظهر العرض رابطًا لآخر شيء مضاف / شيء / 5 ، لن أتمكن من الانتقال إلى الشيء 5 وإلى أي شيء آخر (حتى تغيير عنوان url في المتصفح بشكل صريح). هناك مشكلة أخرى في اختبار templateUrl وهي أنه يمكن تحديد القوالب باستخدام خاصية القالب (كسلسلة أو وظيفة).

يسمح هذا الاختراق بتخطي إعادة تحميل مسار واحد بالضبط ولا يكسر التوجيه.

لقد جربت أيضًا حلًا أقل مطولًا (للاستخدام في وحدة التحكم):

app.factory('location', [
    '$location',
    '$route',
    '$rootScope',
    function ($location, $route, $rootScope) {
        $location.skipReload = function () {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
            return $location;
        };
        return $location;
    }
]);
app.controller('ThingCtrl', ['$scope', '$http', 'location', function ($scope, $http, location) {
    ...
    $scope.submit = function () {
        ...
        $http.post('thing', thing).success(function (id) {
            location.skipReload().path('/thing/' + id).replace();
        });
    };
}]);

يبدو أنه يعمل بشكل جيد.

+1

@ sergey-buturlakin your $ location.skipReload رائع! أنا استخدمه بدلاً من DoNotReloadCurrentTemplate

@ sergey-buturlakin يبدو أن الحل الذي قدمته يعمل بالنسبة لي. شكرا!

بعد تشغيل skipReload() من https://github.com/angular/angular.js/issues/1699#issuecomment -22511464 يظل إعادة التحميل معطلة
يبدو أنه يجب استدعاء un() لاحقًا

يمنع أي إعادة تحميل تالية ، ويجب استدعاؤه قبل تغيير المسار مباشرة.
عند الانتهاء من تغيير المسار - سيتم استدعاء "un".

نعم ، لكنني أردت تخطي إعادة التحميل مرة واحدة فقط ، لكن النهج المقترح يمنع أي إعادة تحميل أخرى

+1

+1

+1

يتخطى PR https://github.com/angular/angular.js/pull/2398 إعادة التحميل مرة واحدة فقط. لا أعرف ما إذا كان قد تم دمج تعارضات مع الرئيسي الحالي. إذا كان الأمر كذلك ، فما عليك سوى مراسلتي وسأصلح الأمر.

أستخدم حل سيرجي ، بينما أسقط المتغير غير المجدي (حسب رأيي) واستدعاء.

هذا يؤدي إلى:

  angular.module('services.locationChanger', [])
    .service('locationChanger', ['$location', '$route', '$rootScope', function ($location, $route, $rootScope) {

        this.skipReload = function () {
            var lastRoute = $route.current;
            $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
            });
            return this;
        };

        this.withoutRefresh = function (url, doesReplace) {
            if(doesReplace){
                $location.path(url).replace();
            }
            else {
                $location.path(url || '/');
            }
        };
    }]);

وأي متصل:

 locationChanger.skipReload().withoutRefresh("/", true);

+1

+1

+1

+1

@ mica16 ألا يتم استخدام المتغير un لإلغاء ربط الحدث؟

لقد أنشأت مكبلين للاختبار ، مع وبدون المتغير un لإلغاء ربط الأحداث ويبدو أنه بدونها يستمر الحدث في الظهور مرارًا وتكرارًا

نعم بالفعل ، يبدو المتغير un غريبًا.
وفقًا للمؤلف الأصلي ، قد يعتبر ذلك مفيدًا .. لكنني لست مقتنعًا بأن هذا هو الحل الأمثل.

فضلت إعادة كتابته ، لكنني حذفت الميزة لأنني لم أعد أتوقعها.

لذا ، اتبعها إذا كان اختبار الوحدة الخاص بك يمكن أن يضمن أنها تعمل كما تتوقع :)

أنتم على حق يا رفاق
كان الحل

app.factory 'location', ['$location', '$route', '$rootScope', '$timeout', ($location, $route, $rootScope, $timeout) ->
  $location.skipReload = ->
    lastRoute = $route.current
    un = $rootScope.$on('$locationChangeSuccess', ->
      $route.current = lastRoute
    )
    $timeout((->
      un()
    ), 1000)
    $location

  $location
]

ثم في وحدة تحكم

location.skipReload().path('/new/path').replace()

+1

+1

+1

+1

هناك طريقة أخرى للقيام بذلك وهي إزالتها من "خطوة" جافا سكريبت الحالية بحيث لا يكون المسار على دراية بالتغيير الذي تم إجراؤه على window.location:

setTimeout(function() {
    window.location.hash = "";
    if (typeof (history.pushState) !== "undefined") {
        history.pushState("", document.title, location.pathname);
    }
}, 0);

+1

+1

+1

+1

ماذا عن استخدام $ anchorScroll؟ كنت أتجول في الشبكة واكتشفت أن هناك بعض الأدوات للقيام بذلك. إنه يعمل بالنسبة لي على الأقل.

يجب عليك التحقق من ذلك: http://docs.angularjs.org/api/ng. $ anchorScroll

+1

هل هذه فكرة سيئة؟ سوف أعترف أنني لم أختبره على نطاق واسع. لم تعجبني فكرة استدعاء طريقة منفصلة قبل تحديد المسار. من وجهة نظر الاستخدام ، يبدو هذا على الأقل أنظف.

لقد قمت بتوسيع وظيفة $ location.path المضمنة ، باستخدام تقنية سيرجي.

App.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
        var original = $location.path;
        $location.path = function (path, reload) {
            if (reload === false) {
                var lastRoute = $route.current;
                var un = $rootScope.$on('$locationChangeSuccess', function () {
                    $route.current = lastRoute;
                    un();
                });
            }

            return original.apply($location, [path]);
        };
    }])

استعمال:

$location.path('/my/path', false);

+1

حلول EvanWinstanley تناسبني ، شكرًا!

+1

يبدو الإصلاح @ EvanWinstanley / sergey جيدًا ولا يقوم بإعادة تحميل وحدة التحكم ، ولكن عند تغيير المسار ، يتم طلب الحلول مرة أخرى.

ستكون حالة الاستخدام الرئيسية الخاصة بي لهذا هي تغيير موقع $ location.path يدويًا دون إعادة تحميل الحلول / وحدة التحكم حتى أتمكن من إجراء التخزين المؤقت.

على سبيل المثال: لدي تحديد يسمح للمستخدم بالاختيار من بين تطبيقات متعددة ، والذي يغير أيضًا $ location.path لعناوين url أجمل. عندما يحدد المستخدم تطبيقًا ، يتم تخزين نتائج استدعاء واجهة برمجة التطبيقات مؤقتًا. حتى مع الإصلاح ، فإنه يقوم دائمًا بالحل مرة أخرى ، وهو أمر غير ضروري لأن النتائج مخزنة مؤقتًا بالفعل.

+1

يعمل حل @ sergey-buturlakin بشكل جيد بالنسبة لي ، فهو لا يعيد تحميل وحدة التحكم ولكنه لا يزال يعيد تحميل وظيفة إعادة التحميل وإرسال الطلب إلى الخادم.

+1

حل EvanWinstanley لا يعمل بالنسبة لي. من ناحية أخرى ، نجح حل

+1

+1

+1

+1
برجاء دعم: $ location.reload ()؛

jvmvik هل جربت $route.current.reload() ؟

7.1.1

لا اخبار عن هذا بعد اكثر من عام؟

+1

+1

لقد أجريت بعض التحسينات على حل سيرجي.
وهو يدعم الآن ، على سبيل المثال ، عناوين url المخصصة لعلامات التبويب (التنقل بين علامات التبويب) دون إعادة تحميل الصفحة بأكملها.

// Original: https://github.com/angular/angular.js/issues/1699#issuecomment-22511464
//
// Usage:
//
// (interception is needed for Back/Forward buttons to work)
//
// location.intercept($scope._url_pattern, function(matched) {
//   // can return false to abort interception
//   var type = matched[1]
//   if (!type) {
//     return;
//   }
//   $scope.safeApply(function() {
//     $scope.data_type = type; 
//     $scope.params.page = 1; 
//     $scope.get_data(); 
//   });
// });
// 
// anywhere in your controller: 
// location.skipReload().path(url);
//
// to replace in history stack:
// location.skipReload().path(url).replace();

app.factory('location', [
    '$location',
    '$route',
    '$rootScope',
    function ($location, $route, $rootScope) {
        var page_route = $route.current;

        $location.skipReload = function () {
            //var lastRoute = $route.current;
            var unbind = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = page_route;
                unbind();
            });
            return $location;
        };

        if ($location.intercept) {
            throw '$location.intercept is already defined';
        }

        $location.intercept = function(url_pattern, load_url) {

            function parse_path() {
                var match = $location.path().match(url_pattern)
                if (match) {
                    match.shift();
                    return match;
                }
            }

            var unbind = $rootScope.$on("$locationChangeSuccess", function() {
                var matched = parse_path();
                if (!matched || load_url(matched) === false) {
                  return unbind();
                }
                $route.current = page_route;
            });
        };

        return $location;
    }
]);

+1

+1

هناك حل بديل آخر لمنع إعادة تحميل المسار عند تغيير مسار الموقع $ ، وهو تعيين مسار المسار الحالي Params لمطابقة مسار الموقع الجديد.

في إعدادات $ routeProvider لديّ مسار إلى / المهام كما يلي

when('/tasks/:section/:taskId?', {
      templateUrl: 'partials/tasks.html',
      controller: 'TaskCtrl',
      reloadOnSearch: false
      })

يحتوي المسار أعلاه على قسمين pathParams ومعرّف TaskId (معرّف TaskId اختياري) ويتم تعيين reloadOnSearch على false.

للتنقل من قل / مهام / صندوق الوارد إلى / مهام / صندوق الوارد / 122 دون إعادة تحميل المسار ، قم بتعيين TaskId pathParam قبل تغيير مسار موقع $ على النحو التالي

$scope.showTask = function(task) {
    // set taskId to prevent route reloading
    $route.current.pathParams ['taskId'] = task.id;
    $location.path('/tasks/'+$route.current.pathParams ['section']+'/'+task.id);
};

لاحظ أن المقطع pathParam لا يحتاج إلى تعيين لأنه تم تعيينه بالفعل بواسطة المسار.

عندما يكتشف المسار أن pathParams المستخرج من مسار الموقع الجديد $ يطابق المسار الحالي pathParams (وتم تعيين reloadOnSearch إلى false) ، فلن يقوم بإعادة تحميل المسار بدلاً من ذلك سيتم تشغيل حدث routeUpdate $.

للانتقال مرة أخرى من / مهام / صندوق الوارد / 122 إلى / مهام / صندوق الوارد دون إعادة تحميل المسار ، احذف TaskId pathParam قبل تغيير مسار موقع $ على النحو التالي

$scope.back = function () {
    // delete taskId to prevent route reloading
    delete $route.current.pathParams ['taskId'];
    $location.path('/tasks/'+$route.current.pathParams ['section']);
};

+1

+: 100:

هل قرأت مقال Derick Bailey حول جهاز التوجيه Backbone http://lostechies.com/derickbailey/2011/08/28/dont-execute-a-backbone-js-route-handler-from-your-code/ ؟ يوفر Backbone هذا الخيار ووفقًا لـ Derick ، ​​يجب عليك دائمًا تجنب تشغيل إعادة التحميل (يبدو أن هذا عكس ما يبدو أن جهاز التوجيه الزاوي يفعله هنا).
هناك 48 "+1" في هذا المنشور ... لا أعتقد أن كل هؤلاء الأشخاص يفعلون شيئًا خاطئًا. إن الاضطرار إلى تخزين var lastRoute = $route.current; واستعادته لاحقًا على $locationChangeSuccess مع $route.current = lastRoute; يبدو أمرًا صعبًا للغاية.
IgorMinar هل لديك أية أفكار؟

حسنًا ، سأمتلك هذا الموضوع للأسبوع القادم ، لذا يمكننا إغلاق هذا الموضوع أخيرًا.

أول الأشياء أولاً ، لا أعتقد أنه يجب إعادة تحميل المسار عندما تتغير قيمة #hash.

website.com/#/my-route#top

website.com/#/my-route#bottom

لذلك عندما يتغير الجزء العلوي إلى الأسفل ، لا ينبغي إعادة التحميل ، ولكن إذا تغيرت قيمة المسار ، فيجب أن يحدث ذلك. يمكننا جميعا أن نتفق على هذا الحق؟

ثانيًا ، وهو الأهم ، نحتاج إلى طريقة سهلة للإشارة إلى أن مسار المسار لن يتم إعادة تحميله عند تغييره ، ولكن هذا سيكون مشكلة إذا تغير جزء سابق من المسار. فلماذا لا يكون لدينا ترميز مختلف لمعلمة المسار باستخدام نقطتين :: للإشارة إلى أنها تعمل كقيمة بدل.

// this will reload the page when the id changes like normal
$routeProvider.register('/users/:id')

// this will reload the page when the id changes, but not the section (since two colons are used)
$routeProvider.register('/users/:id/::section')

ماذا تظنون يا جماعة؟

هذا لا يساعد حقًا في الموقف الذي تريد الانتقال منه:

/users/new

ل

/users/123

بمجرد إنشاء المستخدم الجديد وتعيين معرف ، دون إعادة تحميل المستخدم ، لأنه موجود بالفعل.

لأنه بطريقة ما يجب على المرء تعيين كائن المستخدم الجديد إلى كائن المستخدم الحالي مع معرف 123. هذا هو تطبيق محدد بالأحرى لا؟

لما يستحق ، لا يدعم Ember Router تغيير عنوان URL دون نقل أيٍّ من:

http://stackoverflow.com/questions/19076834/change-url-without-transition

matsko هل يمكننا فقط تمكين المهندس والسماح له أو لها بتحديد ما إذا كان الطريق يجب أن يؤدي إلى تغيير أم لا؟
أنا بخير مع التقصير الجيد.
قم بإنشاء طريقة يمكن للمهندس من خلالها تغيير عنوان url دون تشغيل سلسلة أحداث إعادة التحميل بأكملها. أنا شخصياً لا أوافق على إضافة معلمة إضافية اختيارية مع الخيارات (على سبيل المثال: {reload: false}) في ".path ()" ، ".search ()" ، إلخ.

ChrisCinelli نعم ، ولكن ماذا يحدث عندما يكون هناك معلمتان في تعريف المسار؟ كيف يمكنك منع أحدهما من إعادة التحميل بينما تسمح للآخر بذلك؟ ستكون العلامة ميزة الكل أو لا شيء.

matsko إذن في نهاية التنفيذ ، هل يُنظر في أننا سنكون قادرين على اختيار المعلمات التي تسبب إعادة

cgross cherry ، اختر "نعم" (باستخدام القولون المزدوج). هذه مجرد فكرة في الوقت الحالي لذا لا يوجد شيء ملموس. إذا كان هذا متوافقًا مع خطط Angular 2.0 ، فقد نتمكن من استخدامه أو محاولة استخدام شيء يخطط 2.0 للحصول عليه أو شيء تمتلكه Dart بالفعل (للحفاظ على اتساق واجهة برمجة التطبيقات).

أعتقد أن هذا سيكون مثاليًا ، وسيبدو جيدًا (على الأقل IMO) كجزء من الطريق.

$routeProvider,when("/:categoryName/:id[reload=no]", { ... })

وبعد ذلك ، في وحدة التحكم

$scope.$on("$routeChangeSuccess", function () {
  if ($routeParams.id !== $scope.activeId) {
    // React to ID update without reload
  }
});

نعم شيء من هذا القبيل ، ولكن سيتم استخدام النقطتين المزدوجة ":: id" بدلاً من :id[reload=no] .

ضع في اعتبارك أن هذه مجرد فكرة ، لكن الكثير من الأشخاص هنا يريدون هذه الميزة.

كنت أفكر في إمكانية إضافة خيارات أخرى في النهاية ، لكن أعتقد أنه لا توجد بالفعل أي خيارات أخرى يمكن أن تكون متاحة. من الجيد أيضًا أن ترى هذا الطلب يتم التعامل معه بجدية. تعتبر عناوين URL الجميلة نوعًا من الأمور المهمة بالنسبة للكثير منا.

Matsko +1 للنقطتين المزدوجة ، لكنني أعتقد أنه سيكون من المفيد أيضًا أن تكون قادرًا على تمرير الخيارات إلى المسار () وكذلك لبعض حالات الحافة المذكورة أعلاه

+1 للقولون المزدوج

طلب مني matsko أن أفكر في كيفية تعاملنا مع هذا في جهاز توجيه Angular 2.0. أعلم أنه لا يساعد أولئك الذين يحتاجون إلى هذا من أجل ng1.x لكنني اعتقدت أنه قد يكون ممتعًا بالنسبة لك.

يحتوي جهاز التوجيه الجديد على طريقة navigate يمكنك تمرير _url_ وكائن _options_ اختياري. يعتمد هذا على إمكانيات السجل لجهاز التوجيه Backbone ، لذا فهو يدعم خيارين replace و trigger إذا كنت تريد الانتقال من /users/new إلى /users/123 بدون تسبب في التنقل على الشاشة ، ما عليك سوى تحديد trigger:false . إذا كنت تريد أيضًا استبدال إدخال السجل /users/new بعنوان url الجديد المستند إلى المعرف ، فيمكنك أيضًا تحديد replace:true .

يعد تحديث المسارات من مسار _ جديد إلى مسار _id-based_ دون التسبب في تحويلات DOM ، وما إلى ذلك ، حالة استخدام رئيسية لواجهة برمجة التطبيقات هذه. مثال شائع آخر هو ترقيم الصفحات. على سبيل المثال ، إذا كان لديك شبكة وتريد أن يقوم المستخدم بالصفحات عبر البيانات ، يمكنك استخدام هذا لتحديث الجزء بمعلومات الصفحة الحالية دون التسبب في التنقل. أنا متأكد من أن هناك استخدامات أخرى ، ولكن هذه هي الاستخدامات التي رأيتها مرارًا وتكرارًا في استشاري على مر السنين.

آمل أن تساعد هذه المعلومات. ربما يمكن لجهاز التوجيه 1.x اعتماد هذه التقنية؟

EisenbergEffect ذلك للتأكيد. بالنسبة إلى 1.x ، ستبدو طريقة القيام بذلك دون تغيير المسار كما يلي:

$location.path(value, { trigger : false })

وهذا من شأنه أن يحل محل المسار بشكل فعال دون التسبب في إدراك المسار الجديد + وحدة التحكم. قد يعمل هذا في الوقت الحالي ، ولكن ما هو شعورك حيال فكرة النقطتين المضاعفة :: ؟

بالنسبة لأي شخص آخر هنا ، هل تفضل أن يتم تسهيل تغيير عنوان URL (بدون إعادة تحميل المسار) من خلال المسار أو بواسطة المطور عند تغيير عنوان URL؟

يجب أن يكون هناك مصدر مركزي للحقيقة للموقع ، مثل الخدمة التي
يمكن للطرق والمتصفحات أن تشير إلى وتؤثر على حد سواء ولكنها تظل واحدة
حقيقة
في 1 تموز (يوليو) 2014 ، الساعة 11:28 مساءً ، كتب "ماتياس نيميلا" [email protected] :

EisenbergEffect https://github.com/EisenbergEffect لذلك للتأكيد. ل
1.x ، فإن طريقة القيام بذلك دون تغيير المسار ستبدو كما يلي:

$ location.path (القيمة، {trigger: false})

وهذا من شأنه أن يحل محل المسار بشكل فعال دون التسبب في المسار الجديد

  • تحكم لتصبح على علم. يمكن أن يعمل هذا في الوقت الحالي ، ولكن كيف تشعر
    عن المضاعفة :: فكرة القولون؟

بالنسبة لأي شخص آخر هنا ، هل تفضل تغيير عنوان URL (بدون
إعادة تحميل الطريق) من خلال الطريق أو من قبل المطور
عندما يتم تغيير عنوان URL؟

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/angular/angular.js/issues/1699#issuecomment -47741350.

إليك فكرة أخرى ... اسمح بطريقتين جديدتين لكل تعريف مسار ، قل entering(transitionInfo) و leaving(transitionInfo) أو شيء من هذا القبيل. إذا كانت موجودة ، فسيتم استدعاء طريقة leaving على المسار القديم قبل المغادرة ، ثم يتم استدعاء طريقة entering() في المسار الجديد. سيكون transitionInfo كائنًا مشابهًا لما يلي:

{
  newUrl: ...
  newRoute: ...
  oldUrl: ...
  oldRoute: ...
  cancelRouteChange: false,
  ignoreRouteChange: false
}

في هذه الطريقة ، يمكننا التحقق من المسارات / عناوين url القديمة والجديدة ، ثم إذا كنت تريد تغيير عنوان URL ولكن دون إعادة تشغيل انتقال المسار ، فقم بتعيين ignoreRouteChange إلى true . إذا كنت ترغب في إلغاء تغيير المسار والعودة إلى المسار السابق ، فقم بتعيين cancelRouteChange على true.

يمنح هذا المطور بعد ذلك تحكمًا كاملاً في وقت حدوث انتقالات المسار ، وسيعمل إذا تم تعديل عنوان URL مباشرةً في شريط العنوان ويحدد أيضًا وظيفة اتخاذ قرار بشأن تغيير مسار معين بالقرب من تعريف المسارات الفردية التي تهتم بالتغيير .

أعتقد أن هناك شيئًا مشابهًا في جهاز التوجيه AngularV2 يسمى activate() . EisenbergEffect هل يمكنك تأكيد؟

ما رأيك؟

@ ماتسكو نعم ، يمكن أن تبدو replace أيضًا ، نظرًا لأن هذا مطلوب كثيرًا أيضًا. في هذه الحالة بالذات من /users/new إلى /users/123 أعتقد أنك ستستفيد من كلا الخيارين لأنك لا تريد في الواقع أن يظل /users/new في المكدس الخلفي بعد أن يكون المستخدم الجديد خلقت.

فيما يتعلق بـ :: ، لست متأكدًا من أن هذا مفيد تمامًا. السبب في ذلك ، في مثال المستخدمين أعلاه ، ليس نمط عنوان url هو المهم ، ولكن سياق التطبيق المحدد. على سبيل المثال ، إذا قمت بالانتقال من customers إلى users/123 فأنت تريد التنبيه. أيضًا ، إذا تخلت عن users/new وانتقلت إلى users/456 فأنت أيضًا تريد التنبيه. فقط عندما تكون عند users/new وتنتهي من إنشاء المستخدم الجديد ، فأنت تريد ببساطة تحديث الجزء لتمثيل معرف المستخدم الذي تم إنشاؤه حديثًا دون التسبب في أي انتقال. هذا يعتمد بشكل كبير على ما يفعله المستخدم بالفعل في سياق شاشة المستخدم تلك في تلك النقطة الزمنية.

petebacondarwin إحدى السماح بإعلام المسار ليس شيئًا متاحًا عالميًا جنبًا إلى جنب مع تعريفات المسار. بدلاً من ذلك ، يتم تضمينه داخل وحدة تحكم المستخدم المعينة لأن وحدة التحكم هذه هي جزء من الكود الذي يعرف ما إذا كان يتم إنشاء مستخدم جديد أم لا في هذه اللحظة أم لا ، ببساطة التنقل بعيدًا عن شاشة المستخدم الجديدة إلى مستخدم موجود مسبقًا.

بالنسبة لي ، فإن الطريقة التي يجب اتباعها هي منح التحكم للمتصل الذي يريد تغيير المسار. لذلك أنا بالتأكيد أؤيد خيارين replace و trigger .

EisenbergEffect - أنت على حق. بشكل عام ، هذه المعلومات غير متوفرة على الفور ، على الرغم من أنني أتخيل تنفيذ ذلك بالطريقة التالية:

لدينا خدمة تسمى currentUser ، والتي تحتوي على المستخدم الذي نعمل معه حاليًا. أحب القيام بذلك بشكل عام لأنني لست مرتاحًا لزيادة التحميل على وحدات التحكم الخاصة بي بالكود. إذا كان هذا يبدو محددًا جدًا ، فقد يكون لديك currentEntity ، وهو "الشيء" الحالي الذي تقوم بتحريره / عرضه.

عندئذٍ ، ستكون طريقة المسار enter() قادرة على إدخال هذا الأمر وتحديد ما إذا كان الانتقال إلى هذا المسار سيغير الكيان الحالي بالفعل. إذا لم يكن الأمر كذلك ، فنحن لا نتكبد عناء تشغيل النقل ، فقط قم بتحديث عنوان URL بدلاً من ذلك.

أقدر أن هذا قد يصبح صعبًا بعض الشيء في تطبيق كبير لكنني اعتقدت أنني سأرميها هناك كخيار.

ما هي الحجج ضد إعطاء المتصل (أي الشخص الذي يطلب تغيير المسار / عنوان url) التحكم في ما إذا كان انتقال المسار يحدث بالفعل؟ أتذكر أن IgorMinar كان قلقًا من أن هذا كسر القيود التي تفرضها حالة واحدة من التطبيق على عنوان URL واحد مباشرةً وأن السماح لعنوان URL بالتغيير دون إعادة تشغيل المسار من شأنه أن يضع التطبيق في حالة مختلفة اعتمادًا على الطريقة التي وصلت بها هناك.

petebacondarwin يمكن أن يعمل ذلك مع هذا السيناريو المحدد ، ولكن من الصعب بعض الشيء التعامل مع مثال ترقيم الصفحات الذي ذكرته أعلاه ، والذي قد لا يرغب في تشغيله وليس استبداله ، بينما يريد سيناريو المستخدم الجديد عدم التشغيل بل الاستبدال.

إن معالجة قضية الدولة أمر أكثر تعقيدًا بعض الشيء. والسبب هو أن لدينا عنواني URL يمثلان نفس حالة وحدة التحكم .... لكن الاختلاف يكمن في النموذج. لذلك ، لدينا حالتين مختلفتين في الواقع .... ولكن من منظور UX ، لا نريد هز المستخدم في إجراء الانتقال. من منظور الأداء ، لا نريد التخلص من DOM دون داع وإعادة إنشاء كل شيء. لذلك ، في حالة المستخدم الجديد => انتقال المستخدم المحفوظ ، نريد حقًا تجنب تشغيل الجزء واستبداله أيضًا بحيث لا يعيدك زر الرجوع إلى شاشة المستخدم الجديدة. داخليًا ، سيحتاج جهاز التوجيه أو آلية الموقع فقط إلى تتبع ماهية الجزء الحالي. (أقوم ببعض الافتراضات هناك لأنني لا أعرف كيف يعمل ng1.x في هذا الصدد. مع 2.x نتأكد من تتبع الجزء الحالي / السابق بعناية بغض النظر عن كيفية تغييره.) في سيناريو ترقيم الصفحات ، لا نريد تشغيله لأننا نريد تجربة مستخدم لطيفة للتنقل عبر البيانات ولا نريد التخلص من DOM بلا داع. لكننا نريد الاحتفاظ بالجزء السابق حتى يتمكن المستخدم من استخدام زر الرجوع للخلف خلال صفحات البيانات.

لاحظ أنه في كلتا الحالتين ، لا يتعلق الأمر بعنوان url وحالة التطبيق فحسب ، بل يتعلق أيضًا بكيفية انتقالنا من الحالة الحالية إلى تلك الحالة الجديدة. لا شيء من هذا مهم إذا قمت بإنشاء رابط لموضع معين يؤدي مباشرةً إلى العرض الجديد. لا يهم عندما تنتقل من حالة إلى أخرى في سياق هذه الحالات المحددة للغاية.

+1

+1

+1

+1
وأيضًا ميزة لتغيير عنوان URL دون تغيير المسار

+1 - من اللطيف أن أرى أنني لست وحدي الذي يريد هذا!

+1 ، لم تتم إضافته بعد (

+1

+1

+1

+1

+1

+1

+1

: +1:

أنت أيضاbasarat؟ :ابتسامة:

johnnyreilly لديك خدمة حيث تقوم بحقن $route و $location ويمكنك الحصول على هذه الوظيفة:

/** navigate */
    public navigate(url: string, reload = true) {
        this.$location.url(url);

        // Don't do a controller reload on this navigation. Note: *you* need to be careful not to actually *need* a controller reload
        if (!reload) {
            var lastRoute = this.$route.current;
            var unsub = this.$rootScope.$on('$locationChangeSuccess', () => {
                this.$route.current = lastRoute; // fake this to make the route logic think nothing changed
                unsub();
            });
        }
    }

basarat لطيف!

+1

+1

أحد الأشياء التي ألاحظها مع الحلول الحالية هو أن كتلة حل جهاز التوجيه الخاص بي لا تزال قيد التنفيذ. أي واحد آخر تلاحظ هذا؟ كان من السهل تمرير شيء ما في الكائن route.current $ ، لكن هذا يبدو مخادعًا. أيضًا ، يبدو أن هذه المشكلة لن يتم إصلاحها أبدًا؟ :بكاء:

+1

+1

بالنسبة لأولئك منكم الذين لا يريدون العودة إلى الوراء ... بقدر ما أستطيع أن أقول ، هذا ما لدينا حتى الآن (آسف فنجان قهوة). لسوء الحظ ، هذا لا يعمل بنسبة 100٪ بالنسبة لي. ما زلت أحصل على resolve الخاص بي ويبدو أن أزرار الخلف / الأمام معطلة الآن.

#
# Special $location.path function that allows you to change the url, but not
# send things through the router.
# <strong i="7">@see</strong> https://github.com/angular/angular.js/issues/1699
#
@app.run(['$rootScope', '$location', '$route', '$timeout', ($rootScope, $location, $route, $timeout) ->

    originalPath = $location.path

    $location.path = (url, reload=true) ->
        if ! reload
            lastRoute = $route.current
            if lastRoute
                unsub = $rootScope.$on('$locationChangeSuccess', ->
                    $route.current = lastRoute # fake this to make the route logic think nothing changed
                    $route.current.ignore = true
                    unsub()
                )
                # make sure to clean up and unregister the unsub function
                $timeout( ->
                    unsub()
                , 500)

        originalPath.apply($location, [url])

])

lookfirst أنت unsub مرتين. أفضل: https://github.com/angular/angular.js/issues/1699#issuecomment -54931571

basarat shrug ... لقد أضفت ذلك لأنني وجدت أن الجاني () لم يتم استدعاؤه دائمًا في المثال المفضل لديك. ربما يكون الأفضل هو إضافة حارس في وظيفة الجاني.

unsubbed = false
unsub = ... ->
    if ! unsubbed
        ...
        unsubbed = true
        unsub()

$timeout(unsub, 500)

بغض النظر ، هذا الحل هو فوضى تامة. إنه يكسر كل أنواع الأشياء. نحتاج حقًا إلى إصلاح زاوي معتمد.

لأنني وجدت أن الجاني () لم يتم استدعاؤه دائمًا في المثال المفضل لديك

lookfirst أنت تستخدم location.path أنا أستخدم location.url . قد يؤثر ذلك عليه.

فقط nitpicking (أحب أن أكون مفيدًا): بدلاً من originalPath.apply($location, [url]) يمكنك عمل originalPath.call($location, url) (ربما تعرف هذا بالفعل)

مثير للاهتمام ... يعمل location.url بشكل أفضل كثيرًا (يعمل زر الرجوع مرة أخرى!) ، ولكن يبدو أنه يتسبب في مشكلة أخرى من جانبي. سأضطر إلى البحث في هذا أكثر عندما لا أمارس البرمجة لمدة 10 ساعات متتالية. شكرا على المؤشرات والمناقشة ، حقا!

+1

+1

+1

kuchumovn الحل الخاص بك رائع. إحدى المشكلات التي واجهتها هي أن $routeParams لا يتغير بعد تغيير المسار. لقد قمت بحلها عن طريق استبدال قيمة $routeParams داخل مستمعي الحدث. لست متأكدًا مما إذا كانت هذه هي الطريقة الصحيحة ، لكنها تعمل بالنسبة لي.

app.factory('Location', [
    '$location',
    '$route',
    '$rootScope',
    '$routeParams',
    function ($location, $route, $rootScope, $routeParams) {
        var page_route = $route.current;

        $location.skipReload = function () {
            //var lastRoute = $route.current;
            var unbind = $rootScope.$on('$locationChangeSuccess', function () {
                angular.copy($route.current.params, $routeParams);
                $route.current = page_route;
                unbind();
            });
            return $location;
        };

        if ($location.intercept) {
            throw '$location.intercept is already defined';
        }

        $location.intercept = function(url_pattern, load_url) {

            function parse_path() {
                var match = $location.path().match(url_pattern);
                if (match) {
                    match.shift();
                    return match;
                }
            }

            var unbind = $rootScope.$on("$locationChangeSuccess", function() {
                var matched = parse_path();
                if (!matched || load_url(matched) === false) {
                  return unbind();
                }
                angular.copy($route.current.params, $routeParams);
                $route.current = page_route;
            });
        };

        return $location;
    }
]);

+1

+1

تحدثت إلى IgorMinar شخصيًا أمس ... قال إن المستقبل هو جهاز التوجيه في Angular 2.0 ، والذي سيعود إلى 1.3 قريبًا. شيء للنظر ...

لماذا تريد فقط دمج ui-router في الزاوية؟
يبدو أن جهاز التوجيه uui يحل أي شيء يمكن أن تكون هناك حاجة إليه.

أتفق معelennaro. على الرغم من أن ui-router يتطلب بعض الإبداع والدراسة لجعله يعمل ، إلا أنه يقوم بالخدعة في كل سيناريو صادفته. فضولي ما هي سلبيات استخدام جهاز التوجيه ui وإلقاء موارد Google عليه؟

يبدو أن أيا من الحلول لن ينفذ العزم ، أي أفكار؟

+1

+1

+1 لـ $location.path(value, { trigger : false })
أي تقدم في هذا؟

+1

+1

+1 ماذا عن طريقة منفصلة تمامًا؟ ترك المسار () كما هو ، وإضافة طريقة $ location.hash التي تغير عنوان url الخاص بالمتصفح بدون إعادة تحميل وحدة التحكم. هذا يسمح لنا بالتحكم في التنقل الخلفي للمتصفح وهو سيناريو صالح لحالة الاستخدام في التطبيقات الغنية.

+1

يتم حاليًا استخدام المقتطف هنا في هذه الصفحة: http://joelsaupe.com/programming/angularjs-change-path-without-reloading/

+1

+1

+1

كان الحل الذي وجدته هو إضافة حالة فرعية بعنوان url مطلق.

$stateProvider.state('state.child', {
    url: '^/some-other-url'
});

ثم قم ببساطة بعمل $ state.go (". child") وهذا يجب أن يغير عنوان url إلى العنوان الذي تريده دون إعادة التحميل وإرضاء الجميع. لاحظ أن علامة الإقحام ، التي تشير إلى أن عنوان url لا يرث من الأصل .. استغرقني بعض الوقت لمعرفة ذلك.

+1

+1

+1

+1

+1

+1

+1

btford كيف يتم التعامل مع هذا (إن وجد) في componentRouter ؟

شكرًا لـ balsarori على حل بسيط وعملي .

تم وضعه في الأعلى للسماح بتحديث معلمات المسار $route ، بدون إعادة تحميل وحدة التحكم.

يستخدم console.log بدلاً من $log حيث يمكننا ببساطة تجريد جميع السجلات لإنشاءات الإنتاج باستخدام uglifyjs.

تحرير: الإصلاح عند الاستخدام في مشروع:

/**
 * parameter handling
 */

'use strict';

angular.module('route-params', [
  'ng',
  'ngRoute',
])
.service('routeParams', function(
  $route,
  $location
) {
  var R = {};

  /**
   * <strong i="15">@ngdoc</strong> method
   * <strong i="16">@name</strong> routeParams#replace
   *
   * <strong i="17">@description</strong>
   * Replace route params, including path params, without reloading controller.
   *
   * Causes `$route` service to update the current URL, replacing
   * current route parameters with those specified in `params`.
   *
   * Provided property names that match the route's path segment
   * definitions will be interpolated into the location's path, while
   * remaining properties will be treated as query params.
   *
   * If `options.reload` is truthy, the current controller is reloaded.
   *
   * If `options.history` is truthy, the browser history is updated.
   * If `options.history` is undefined, the browser history is only updated
   * when changing value of any existing `$route` parameter,
   * ie. not when adding a previously undefined `$route` parameter.
   *
   * <strong i="18">@param</strong> {!Object<string, string>} params mapping of URL parameter names to values
   * <strong i="19">@param</strong> {!Object<string, boolean>} options `history` and `reload` options.
   *
   * <strong i="20">@returns</strong> {Object} self
   */
  R.replace = function(params, options) {
    var key, value, updateRequired;
    options = options || {};

    // Convert params to strings, and check if they differ from current route params.
    // If `options.history` is undefined, and passed params update any current route params, then set it to true.
    var currentParams = $route.current.params;

    console.log('route: params: replace', {last: angular.copy(currentParams), next: params,
      route: $route.current, options: options});

    if (!$route.current.$$route) {
      // Can't change location.
      return;
    }
    var currentPath = $route.current.$$route.originalPath;
    var history = options.history;

    for (key in params) {
      // jshint eqnull: true
      value = params[key] = (params[key] == null ? undefined : params[key] + '');

      if (value !== currentParams[key]) {
        updateRequired = true;

        console.log('route: params: replace: ' + (currentPath.search(':\\b' + key + '\\b') ? 'path.' : 'search.') +
          key + ' = ' + (key in $route.current.params ? $route.current.params[key] + ' -> ' : '') + params[key]);

        if (history === undefined && key in currentParams) {
          console.log('route: params: replace: update history: ' + key + ' = ' + currentParams[key] + ' -> ' + value);
          history = true;
        }
      }
    }

    if (updateRequired) {
      // If `options.reload` is falsey, then set current route `reloadOnSearch` to false,
      // and make passed path params equal with current route path params,
      // so that `$route` treats the change as update only, and does not broadcast `$routeChangeStart` event.
      //
      // See https://github.com/angular/angular.js/issues/1699#issuecomment-45048054
      // and https://github.com/angular/angular.js/tree/v1.3.x/src/ngRoute/route.js#L484
      // and https://github.com/angular/angular.js/tree/v1.3.x/src/ngRoute/route.js#L539
      if (!options.reload) {
        // Set current route `reloadOnSearch` to false.
        $route.current.$$route.reloadOnSearch = false;

        // Add any passed path params to current route path params, and convert them to strings.
        // Path params are detected by searching for respective name group `:key[*?]` in current route path.
        for (key in params) {
          if (currentPath.search(':\\b' + key + '\\b') !== -1) {
            $route.current.pathParams[key] = params[key];
          }
        }

        // Add any current route path params to passed params, if not set there already.
        for (key in $route.current.pathParams) {
          if (!(key in params)) {
            params[key] = $route.current.pathParams[key];
          }
        }

        // TODO: push state if `options.history` is truthy.
      }
      // If `options.history` is falsey, and controller is reloaded,
      // then make `$location` replace current history state, instead of pushing a new one.
      else if (!history) {
        $location.replace();
      }

      $route.updateParams(params);

      // Update current route params, so the change is reflected immediatelly,
      // and nearby replace() call work correctly.
      for (key in params) {
        $route.current.params[key] = params[key];
      }
    }

    return R;
  };

  return R;
});

ما هو الوضع الحالي لهذه المشكلة؟ سيتم حلها في جهاز التوجيه الجديد؟ في الوقت المحدد لإصدار 1.4؟ قريبا؟

أواجه نفس المشكلة ولكن مع معلمات سلسلة الاستعلام. لا أريد إعادة التحميل عند تغييرها. لكن لا يمكنني تعطيل reloadOnSearch لأنني بحاجة إلى معرفة ما إذا كان المستخدم يغير سلسلة الاستعلام يدويًا! :)

شكرا!

marcalj fwiw ، اخترقنا هذا الحل من خلال خدمة أبقت عنوان url متزامنًا مع شريط العناوين حتى نتمكن من تعطيل reloadOnSearch والاستيلاء على معلمات الاستعلام. أيضًا ، يمكن للمستخدمين التنقل في عنوان URL مباشرةً عبر إشارة مرجعية أو رابط.

مع ng-router أو ui-router؟ هل يمكنك أن تزودني برابط بالرمز أو شيء من هذا القبيل؟

ربما يمكن حل هذا باستخدام جهاز توجيه جديد ، يمكنني انتظاره لأن مشروعي لم ينته بعد.

شكرا!

marcalj مثالنا معقد بعض الشيء وربما عفا عليه الزمن ولكن انظر إلى https://github.com/irthos/mngr/blob/master/app.js وتحقق من السطر 10. يستخدم طريقة api.loadState الخاصة بنا التي تحدد المعلمات في عنوان url لبناء الحالة المناسبة.

كان NgSilent هو الحل بالنسبة لي.
انظر إلى https://github.com/garakh/ngSilent
تم الاختبار مع ngRoute 1.3.15

لقد استخدمت كلاً من حل @ sergey-buturlakin و @ kuchumovn ، وأواجه نفس المشكلة باستمرار.

في الصفحة المعنية (pagex) أستخدم location.skipReload وهي تعمل بشكل رائع - يمكنني تحديث المسار مرارًا وتكرارًا دون تغيير المسار. إذا استخدمت موقع $ location.path فعليًا لتغيير المسار بعيدًا عن pagex إلى وحدة تحكم جديدة ، فهذا يعمل ، ولكن إذا قمت بالضغط على زر الرجوع للعودة إلى الصفحة ، ثم حاولت الانتقال إلى صفحة أخرى ، فلن يمكنني ذلك بعد الآن غير مساري بعد الآن بدون تحديث المتصفح. هل هناك طريقة للتغلب على ذلك؟

+1

+1. أنا أحب نهج القولون المزدوج الذي اقترحه ماتياس

+1

إنها حالة استخدام شائعة لتطبيق الصفحة الواحدة لعدم إعادة تحميل الصفحة عند تغيير المسار ،
غريب جدًا لماذا لم يتم تضمينه بعد في الزاوي.
البرنامج المساعد الذي تم إنشاؤه بناءً على حل EvanWinstanley :
https://github.com/anglibs/angular-location-update

دعنا نعيد النظر في هذا في 1.5. يوجد علاقات عامة مرتبطة بالرقم 5860

أحتاج إلى نفس الوظيفة لتحديث سلسلة الاستعلام دون تشغيل وحدة تحكم المسار! :)

شيء من هذا القبيل: $location.searchSilent('sf', SearchFilter.getForRouteParams());

$ location.path (href)؛
النطاق. $ apply ()؛
هو الحل !!
نحتاج إلى إبلاغ الزاوي بالتغيير باستخدام $ application ()

لم يتم فتح هذا الموضوع منذ عامين لأنه لم يتم إخطار الزاوية - نريد تغيير جزء من المسار دون استدعاء كل شيء.

petebacondarwin سيكون من الجيد ان يكون ليس فقط تحديث مسار الموقع دون تحديث، ولكن أيضا تحديث بارامس المسار دون تحديث ... مثل نفذت فوق https://github.com/angular/angular.js/issues/1699#issuecomment -96126887

لقد عمل حل jicasada جيدًا بالنسبة لي! شكرا!

jicasada هل هذا يعمل مع جهاز التوجيه ui؟ لقد أشرت إلى خطأ في جهاز توجيه واجهة المستخدم حيث لا يعمل reloa dOnSearch: false إذا كان الوالد والطفل يشتركان في نفس عنوان URL. إذا قمت بالانتقال إلى حالة الطفل باستخدام معلمة الطلب المحدثة ، فسوف تتصل بوحدة التحكم الرئيسية مرتين.

+1

+1

أؤكد أن ngSilent يقوم بهذه المهمة على أكمل وجه. ومع ذلك ، فإن الحل الرسمي سيكون موضع تقدير كبير.

الحل بشكل أساسي هو إضافة معامل إضافي إلى $ location.path ().

app.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
    var original = $location.path;
    $location.path = function (path, reload) {
        if (reload === false) {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
        }
        return original.apply($location, [path]);
    };
}]);

ثم استخدم فقط مثل هذا

$location.path('/path/that/you/need', false);

يجب أن أكون قادرًا فقط على عمل $ location.replace () تمامًا مثل وظيفة window.location.replace. هذا أمر سخيف لأن كل إنشاء في عملية CRUD سيواجه هذه المشكلة دائمًا.

(و) +1

+1

أنصحك باستخدام "معلمة البحث" مثل هذا:
/thing?id=1234
لا تقم بتكوين المعلمة في موفر جهاز التوجيه ، فلن تقوم بإعادة تحميل العرض ووحدة التحكم.
إذا كنت ترغب في الحصول على الهوية
$location.search().id //1234
تضمين التغريدة

عرض توضيحي http://codepen.io/dolymood/details/jrEQBx/
استخدم decorator لتصميم الديكور ngViewDirective

+1

+1

+1

+1

+1

+1

+!

ما يكفي من +1 بالفعل :-)
وصلتنا الرسالة. سننظر في هذا قبل عيد الميلاد!

تم إغلاقه ب # 15002.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات