Javascript 是否可以扩展Angular JS 1.2.18$log功能?

Javascript 是否可以扩展Angular JS 1.2.18$log功能?,javascript,angularjs,toastr,angularjs-decorator,Javascript,Angularjs,Toastr,Angularjs Decorator,我想弹出一条toastr消息来显示$log消息。即: $log.info('test')); 在AngularJS 1.2.19及更高版本中,这似乎是一个很好的解决问题的方法。当然,我使用的是1.2.18。在1.2.18中有没有办法做到这一点 理想情况下,我希望扩展现有的功能,而不是完全覆盖它 我不想修改角度源。decorator机制是创建获取先前定义并返回其新版本的提供程序的缩写 因此,您可以按如下方式模拟此功能: module.provider('$log', function ($log

我想弹出一条toastr消息来显示$log消息。即:

$log.info('test'));
在AngularJS 1.2.19及更高版本中,这似乎是一个很好的解决问题的方法。当然,我使用的是1.2.18。在1.2.18中有没有办法做到这一点

理想情况下,我希望扩展现有的功能,而不是完全覆盖它


我不想修改角度源。

decorator机制是创建获取先前定义并返回其新版本的提供程序的缩写

因此,您可以按如下方式模拟此功能:

module.provider('$log', function ($logProvider) {
    // $logProvider here is the one previously defined, from 'ng'
    // unless someone else is overriding too.
    this.$get = function ($injector) {
        // Invoke the original provider.
        var $log = $injector.invoke($logProvider.$get);
        var oldInfo = $log.info;
        // Override the method.
        $log.info = function info() {
            oldInfo.apply(this, arguments);
            // (not actually useful to alert arguments; just an example)
            alert(arguments);
        }
        return $log;
    }
});
当然,这会修改所有依赖项的对象,即使他们对标准
$log
接口非常满意,这意味着您无法在应用程序中直接看到哪些服务依赖于标准接口,哪些依赖于扩展接口。如果您只想通过包装来更改现有方法的行为(例如,将日志发送到您的服务器,或显示您在问题中提到的烤面包机),这可能很有用,但添加现有调用方不希望的其他方法可能是一个危险的选择,您可能会意外中断与标准接口的兼容性

相反,最好提供一种新的服务,您可以在需要扩展的地方使用,并将内置的
$log
界面作为标准。通过这种方式,可以更容易地区分不同之处,并避免在标准呼叫者中发生意外的行为变化。这看起来与上面的类似,但在细节上略有不同:

module.provider('anotherLog', function ($logProvider) {
    this.$get = function ($injector) {
        var $log = $injector.invoke($logProvider.$get);

        // Create a new object rather than extending the existing one in-place.
        // This way the new method is only visible to callers that request
        // 'anotherLog' instead of just '$log'.
        var anotherLog = angular.extend(Object.create($log), {
            sayHello: function sayHello() {
                console.log('Hello!');
            }
        })

        return anotherLog;
    }
});
这两种方法都利用了一个事实,即在应用程序初始化期间,使用一个单独的“提供者注入器”来处理提供者之间的依赖关系。这与创建应用程序后使用的主
$injector
不同。提供程序注入器包含到目前为止已定义的所有提供程序,但不包含结果服务,如
$log
。provider函数本身由provider注入器注入,而其
$get
方法(如这些示例所示)由主
$injector
注入


由于这一区别,如果您依赖任何其他服务来显示您的烤面包机,则必须依赖它们来实现
$get
方法本身,而不是整个提供者。这将允许您访问主
$injector
中的服务,而不仅仅是来自提供程序injector的提供程序。

装饰程序机制是创建提供程序的简写,该提供程序获取以前的定义并返回其新版本

因此,您可以按如下方式模拟此功能:

module.provider('$log', function ($logProvider) {
    // $logProvider here is the one previously defined, from 'ng'
    // unless someone else is overriding too.
    this.$get = function ($injector) {
        // Invoke the original provider.
        var $log = $injector.invoke($logProvider.$get);
        var oldInfo = $log.info;
        // Override the method.
        $log.info = function info() {
            oldInfo.apply(this, arguments);
            // (not actually useful to alert arguments; just an example)
            alert(arguments);
        }
        return $log;
    }
});
当然,这会修改所有依赖项的对象,即使他们对标准
$log
接口非常满意,这意味着您无法在应用程序中直接看到哪些服务依赖于标准接口,哪些依赖于扩展接口。如果您只想通过包装来更改现有方法的行为(例如,将日志发送到您的服务器,或显示您在问题中提到的烤面包机),这可能很有用,但添加现有调用方不希望的其他方法可能是一个危险的选择,您可能会意外中断与标准接口的兼容性

相反,最好提供一种新的服务,您可以在需要扩展的地方使用,并将内置的
$log
界面作为标准。通过这种方式,可以更容易地区分不同之处,并避免在标准呼叫者中发生意外的行为变化。这看起来与上面的类似,但在细节上略有不同:

module.provider('anotherLog', function ($logProvider) {
    this.$get = function ($injector) {
        var $log = $injector.invoke($logProvider.$get);

        // Create a new object rather than extending the existing one in-place.
        // This way the new method is only visible to callers that request
        // 'anotherLog' instead of just '$log'.
        var anotherLog = angular.extend(Object.create($log), {
            sayHello: function sayHello() {
                console.log('Hello!');
            }
        })

        return anotherLog;
    }
});
这两种方法都利用了一个事实,即在应用程序初始化期间,使用一个单独的“提供者注入器”来处理提供者之间的依赖关系。这与创建应用程序后使用的主
$injector
不同。提供程序注入器包含到目前为止已定义的所有提供程序,但不包含结果服务,如
$log
。provider函数本身由provider注入器注入,而其
$get
方法(如这些示例所示)由主
$injector
注入


由于这一区别,如果您依赖任何其他服务来显示您的烤面包机,则必须依赖它们来实现
$get
方法本身,而不是整个提供者。这将允许您访问主
$injector
中的服务,而不仅仅是提供者injector中的提供者。

您也可以使用1.2.18中的装饰器。怎么了?我用链接读到了$provide。当我将选择器更改为1.2.18时,我得到一个404错误。看起来好像是个虫子?我进一步调查了我的错误消息,发现我有一个不同的问题。你是对的,它在1.2.18中确实有效。谢谢否决投票的原因?你也可以使用1.2.18的装饰程序。怎么了?我用链接读到了$provide。当我将选择器更改为1.2.18时,我得到一个404错误。看起来好像是个虫子?我进一步调查了我的错误消息,发现我有一个不同的问题。你是对的,它在1.2.18中确实有效。谢谢否决票的原因?