javascript - 可以扩展 Angular JS 1.2.18 $log 功能吗?

标签 javascript angularjs toastr angularjs-decorator

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

$log.info('test'));

似乎在 AngularJS 1.2.19 及更高版本中,$provide.decoratorextend the functionality of $log 的好方法。当然,我用的是1.2.18。在 1.2.18 中有办法做到这一点吗?

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

我不想修改 Angular 源代码。

最佳答案

装饰器机制是创建一个提供者的简写,该提供者获取先前的定义并返回它的新版本。

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

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 接口(interface)非常满意,并且意味着您无法直接在应用程序中查看哪些服务依赖取决于标准接口(interface),哪些取决于您的增强接口(interface)。如果您只想通过包装来更改现有方法的行为(例如,将日志发送到您的服务器,或者如您在问题中提到的那样显示 toastr ),这可能很有用,但添加额外的方法可能是一个冒险的选择现有调用者不期望的方法,您可能会意外地破坏与标准接口(interface)的兼容性。

相反,最好提供一项新服务,您可以在您知道需要扩展的地方使用该服务,并将内置 $log 接口(interface)保留为标准。这样可以更容易地区分差异,并避免标准调用者发生意外的行为变化。这看起来与上面类似,但在细节上略有不同:

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;
    }
});

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

由于这种区别,如果您依赖任何其他服务来显示 toastr ,则必须依赖它们来获取 $get 方法本身,而不是整个提供程序。这将允许您访问主 $injector 中的服务,而不仅仅是来自提供程序注入(inject)器的提供程序。

关于javascript - 可以扩展 Angular JS 1.2.18 $log 功能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27661001/

相关文章:

javascript - 正则表达式验证器 - 如何包含某些特殊字符

javascript - 倾斜的 Highcharts 轴标签与图例重叠

javascript - 如何在 angularjs 应用程序中注销时删除/清除存储在范围变量中的数据?

javascript - 尝试使用 toastr 时出现错误 "toastr is not a function error"

javascript - 使用 Sammy.js 取消路由而不影响历史记录

javascript - 如何将 ID 分配给 toastr.js 通知并根据需要更新它

javascript - 处理未格式化的数据数组

javascript - 尝试为 qx.ui.embed.Html 制作一个带有 Non-Native 、 qooxdoo-Themed 滚动条的小部件

AngularJS 转换响应

AngularJS "No pending request to flush",同时使用 $resource 对 Controller 进行单元测试